![](/img/trans.png)
[英]Why does the Rust compiler error with "cannot borrow as immutable because it is also borrowed as mutable" after moving the variable into a scope?
[英]Why does moving a value into a closure still have the error message “cannot borrow immutable local variable as mutable”?
在下面的代码中,我明确地强制将main
函数中的name
移到闭包中,并且一切正常:
fn main() {
let name = String::from("Alice");
let welcome = || {
let mut name = name;
name += " and Bob";
println!("Welcome, {}", name);
};
welcome();
}
我本以为在闭包的开头添加一个move
会完成同样的事情,并导致值被移动并创建FnOnce
:
fn main() {
let name = String::from("Alice");
let welcome = move || {
name += " and Bob";
println!("Welcome, {}", name);
};
welcome();
}
但是,相反,我收到错误消息:
error[E0596]: cannot borrow immutable local variable `welcome` as mutable
--> main.rs:9:5
|
4 | let welcome = move || {
| ------- help: make this binding mutable: `mut welcome`
...
9 | welcome();
| ^^^^^^^ cannot borrow mutably
error[E0596]: cannot borrow captured outer variable in an `FnMut` closure as mutable
--> main.rs:5:9
|
5 | name += " and Bob";
| ^^^^
什么是思考的正确方法move
在这种情况下,封闭?
我本以为在结束处添加一个
move
会完成相同的事情,……
它做同样的事情。 您只是忘了宣布name
而welcome
视为可变的。 这段代码可以正常工作:
fn main() {
let mut name = String::from("Alice");
let mut welcome = move || {
name += " and Bob";
println!("Welcome, {}", name);
};
welcome();
}
闭包的两个版本都将name
移入闭包。 在第一个版本中,这是由于使用闭包内部的name
而导致的。 第二个版本不使用name
,而是使用move
关键字强制移动。
…并导致值被移动并创建
FnOnce
。
将值移到闭包中不会使其FnOnce
。 如果关闭消耗捕捉值,就FnOnce
,因为它显然可以做到这一点只有一次。 因此,闭包的第一个版本是FnOnce
,因为它使用了name
。 上面的Clousre是FnMut
,可以多次调用。 两次调用将导致输出
Welcome, Alice and Bob
Welcome, Alice and Bob and Bob
(我在上面FnOnce
使用了函数特征名称。实际上, 每个闭包都实现了FnOnce
,因为每个闭包至少可以调用一次。某些闭包可以多次调用,因此它们又是FnMut
。还有一些闭包可以被多次调用不会改变其捕获状态,因此除其他两个特征外,它们均为Fn
。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.