我有以下代码片段:
fn f<T: FnOnce() -> u32>(c: T) {
println!("Hello {}", c());
}
fn main() {
let mut x = 32;
let g = move || {
x = 33;
x
};
g(); // Error: cannot borrow as mutable. Doubt 1
f(g); // Instead, this would work. Doubt 2
println!("{}", x); // 32
}
Run Code Online (Sandbox Code Playgroud)
疑问1
我什至无法运行一次。
疑问2
...但我可以根据需要多次调用该闭包,只要我通过f. 有趣的是,如果我声明它FnMut,我会得到与疑问 1 相同的错误。
疑点3
和特征定义self中指的是什么?这就是关闭本身吗?还是环境?例如,来自文档:FnFnMutFnOnce
pub trait FnMut<Args>: FnOnce<Args> {
extern "rust-call" …Run Code Online (Sandbox Code Playgroud) 我有一个Vec<State>列表,想要搜索一个元素并获取对其的可变引用。如果不存在,则应创建一个新的默认元素并将其添加到列表中:
struct State {
a: usize,
}
fn print_states(states: &Vec<State>) {
for state in states {
print!("State{{a:{}}} ", state.a);
}
println!();
}
fn main() {
let mut states = vec![State { a: 1 }, State { a: 2 }, State { a: 3 }];
print_states(&states);
let mut state = match states.iter_mut().find(|state| state.a == 2) {
Some(state) => state,
None => {
let new_state = State { a: 3 };
states.push(new_state);
states.last().unwrap()
}
};
state.a = 4;
drop(state);
print_states(&states); …Run Code Online (Sandbox Code Playgroud) 这是食谱应用程序的一部分。我在我写的食谱课上。Ingredient是我写的另一个类。这个想法是将成分及其数量(作为 Int)存储在地图中。
在类主体中,我将地图声明为:
var ingredients: Map<Ingredient, Int>
Run Code Online (Sandbox Code Playgroud)
在 init{} 主体中:
ingredients = mutableMapOf<Ingredient, Int>()
Run Code Online (Sandbox Code Playgroud)
问题来了——这个函数是添加一种成分。如果成分已在地图中,它会更新数量。put() 方法应该执行此操作,但 Android Studio 将其变为红色,当我将鼠标悬停在“put”一词上时,它会显示“未解析的引用:put”。加号也有红色下划线。我认为这是可变映射的基本部分。我哪里出错了?(别担心 - 会有“其他”部分!)
fun addIngredientAndAmount(ingredient: Ingredient, quantity: Int) {
if (ingredients.containsKey(ingredient)) {
val oldQuantity = ingredients[ingredient]
ingredients.put(ingredient, oldQuantity + quantity)
}
}
Run Code Online (Sandbox Code Playgroud) #include <utility>
void f(auto const& fn1)
{
{
auto fn2 = std::forward<decltype(fn1)>(fn1);
auto fn3 = std::forward<decltype(fn2)>(fn2); // ok
fn3();
}
[fn2 = std::forward<decltype(fn1)>(fn1)]
{
auto const fn3 = fn2;
auto fn4 = std::forward<decltype(fn3)>(fn3); // ok
fn4();
auto fn5 = std::forward<decltype(fn2)>(fn2); // error
fn5();
}();
}
int main()
{
f([] {});
}
Run Code Online (Sandbox Code Playgroud)
为什么 std::forward 在 lambda 体内不起作用?
更新信息:
g++ 可以,但 clang++ 拒绝它。谁是正确的?
在尝试重构运行良好的 Rust 应用程序时,我尝试将循环的内容分离到一个新函数中。然而,在这个新重构的函数中,我需要传递一个必须可变的参数,并通过引用传递。突然之间,绝对内联工作的代码仅仅因为可变的引用传递而崩溃了。
我的问题是:有人可以解释一下为什么这样的“简单”更改不起作用吗?(即重构出原本未更改的代码的新函数)
我有一个关于该问题的最小演示,以及下面的一些工作比较。这是该代码的错误:
error[E0499]: cannot borrow `str_to_int` as mutable more than once at a time
--> src/main.rs:30:22
|
30 | get_key(key, &mut str_to_int);
| ^^^^^^^^^^^^^^^ `str_to_int` was mutably borrowed here in the previous iteration of the loop
Run Code Online (Sandbox Code Playgroud)
示例代码:
use std::collections::BTreeMap;
fn get_int (
key: u32,
values: &mut BTreeMap<u32, u32>,
) -> &u32 {
values.entry(key).or_insert_with(|| { 1 })
}
fn get_key<'a> (
key: &'a str,
values: &'a mut BTreeMap<&'a str, u32>,
) -> &'a u32 {
values.entry(key).or_insert_with(|| { 1 …Run Code Online (Sandbox Code Playgroud) 我的问题涉及API设计.
假设我正在设计一个矢量(数学/物理意义).我想要一个不可变的实现和一个可变的实现.
然后我的矢量看起来像这样:
public interface Vector {
public float getX(); public float getY();
public X add(Vector v);
public X subtract(Vector v);
public X multiply(Vector v);
public float length();
}
Run Code Online (Sandbox Code Playgroud)
我想知道如何确保同时具有可变和不可变的实现.我真的不喜欢java.util.List的方法(默认允许可变性)和Guava的不可变实现所具有的UnsupportedOperationException().
如何使用这两种实现设计"完美"接口或抽象类Vector?
我想过这样的事情:
public interface Vector {
...
public Vector add(Vector v);
...
}
public final class ImmutableVector implements Vector {
...
public ImmutableVector add(Vector v) {
return new ImmutableVector(this.x+v.getX(), this.y+v.getY());
}
...
}
public class MutableVector implements Vector {
...
public MutableVector add(Vector v) {
this.x += v.getX();
this.y += …Run Code Online (Sandbox Code Playgroud) 我想在F#对象表达式中有一个可变状态.第一种方法是使用ref单元格如下:
type PP =
abstract member A : int
let foo =
let a = ref 0
{ new PP with
member x.A =
let ret = !a
a := !a + 1
ret
}
printfn "%A" foo.A
printfn "%A" foo.A
printfn "%A" foo.A
printfn "%A" foo.A
Run Code Online (Sandbox Code Playgroud)
一种不同的方法如下:
type State(s : int) =
let mutable intState = s
member x.state
with get () = intState
and set v = intState <- v
[<AbstractClass>]
type PPP(state : State) =
abstract member …Run Code Online (Sandbox Code Playgroud) 我有2本词典.
dict1={('SAN RAMON', 'CA'): 1, ('UPLAND', 'CA'): 4, ('POUGHKEESIE', 'NY'): 3, ('CATTANOOGA', 'TN'): 1}
dict2={('UPLAND', 'CA'): 5223, ('PORT WASHING', 'WI'): 11174, ('PORT CLINTON', 'OH'): 6135, ('GRAIN VALLEY', 'MO'): 10352, ('GRAND JUNCTI', 'CO'): 49688, ('FAIRFIELD', 'IL'): 5165}
Run Code Online (Sandbox Code Playgroud)
这些只是样本,实际上每个dict都有数百个条目.我正在尝试合并两个字典并创建包含{dict1.values():dict2.values()}的字典3,但前提是该字母出现在两个字典中.所以,dict3中的一个条目看起来像
{4:5223} # for 'UPLAND', 'CA' since it appears in both dict1 and dict2
Run Code Online (Sandbox Code Playgroud)
这只是我写的更大功能中的一小步.我打算尝试类似的东西:
for item in dict1.keys():
if item not in dict2.keys():
del item
return dict[(dict1.keys())=(dict2.keys())]
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚如何确保来自dict1的投诉数量与dict2中引用的同一城市相匹配.
许多语言都支持不可变类型 - 一旦构造了这种类型的值,就无法以任何方式对其进行修改.我不会偏离这些类型的好处,因为这已在其他地方广泛讨论过.(参见http://codebetter.com/patricksmacchia/2008/01/13/immutable-types-understand-them-and-use-them/)
我想在C++中创建一个轻量级的不可变记录类型.这样做的一个显而易见的方法是const所有成员.例如:
struct Coordinates {
const double x;
const double y;
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,以这种方式声明的类型不支持复制赋值,因此不能与STL容器一起使用,这是一个相当致命的缺点.我认为没有任何方法可以解决这个问题,但如果有人能看到,我会很感激.
至于它的价值,据我所知,C++正在混淆两件事:a)你是否可以为变量赋值,b)是否可以在构造之后修改"values"(= objects).在例如Scala中,区别更加清晰
valvs var:a var可以有一个绑定到它的新值,一个val不能所以我可以写下面的内容:
val val_mutable = collection.mutable.Map(1 -> "One")
val val_immutable = collection.immutable.Map(1 -> "One")
var var_mutable = collection.mutable.Map(1 -> "One")
var var_immutable = collection.immutable.Map(1 -> "One")
Run Code Online (Sandbox Code Playgroud)
vars可以反弹以指向其他值:
//FAILS: val_immutable = collection.immutable.Map(2 -> "Two")
//FAILS: val_mutable = collection.mutable.Map(2 -> "Two")
var_mutable = collection.mutable.Map(2 -> "Two")
var_immutable = collection.immutable.Map(2 -> "Two")
Run Code Online (Sandbox Code Playgroud)
可修改的集合可以修改: …
我有这个简单的不可变对象:
public class Alt {
public LinkedList<Integer> list = new LinkedList<Integer>();
public void refresh() {
Random rand = new Random();
list.clear();
for (int i = 0; i < 50; i++) {
list.add(rand.nextInt(32));
}
}
public void compare(Alt alt) {
for (int i = 0; i < list.size(); i++) {
System.out.println(alt.list.get(i) + " " + list.get(i));
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是这个类是一个不可变对象,例如当我运行时:
Alt a = new Alt();
a.refresh();
Alt b = a;
b.refresh();
a.compare(b);
Run Code Online (Sandbox Code Playgroud)
返回的值是相同的,对象b就像是对象a的快捷方式,并且或多或少是重复的.有没有办法让它分开?或者我是以完全错误的方式做到这一点.
mutable ×10
immutability ×3
rust ×3
c++ ×2
dictionary ×2
java ×2
borrowing ×1
c++20 ×1
class-design ×1
closures ×1
const ×1
f# ×1
kotlin ×1
lambda ×1
move ×1
python ×1
ref ×1
refactoring ×1
reference ×1