rust - 为什么将值移动到闭包中仍然有错误消息 "cannot borrow immutable local variable as mutable"?

标签 rust

在下面的代码中,我明确地强制将 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 的正确方法是什么?

最佳答案

I would have thought that adding a move to the beginning of the closure would accomplish the same thing, …

它有点做同样的事情。您只是忘记将 namewelcome 声明为可变的。此代码工作正常:

fn main() {
    let mut name = String::from("Alice");

    let mut welcome = move || {
        name += " and Bob";
        println!("Welcome, {}", name);
    };

    welcome();
}

两个版本的闭包都会导致 name 被移动到闭包中。在第一个版本中,这是由在闭包内使用 name 隐式引起的。第二个版本不使用 name,而是使用 move 关键字强制移动。

… and result in the value being moved and the creation of a FnOnce.

将值移动到闭包中不会使其成为 FnOnce。如果一个闭包消费一个捕获的值,它就变成了FnOnce,因为它显然只能这样做一次。因此,闭包的第一个版本是 FnOnce,因为它使用 name。上面的clousre是FnMut,可以多次调用。调用它两次导致输出

Welcome, Alice and Bob
Welcome, Alice and Bob and Bob

(我在上面草率地使用了函数特征名称。事实上,每个 闭包都实现了 FnOnce,因为每个闭包至少可以被调用一次。有些闭包可以多次调用,所以它们是FnMut。而一些可以多次调用的闭包不会改变它们的捕获状态,所以它们是 Fn 除了其他两个特征。)

关于rust - 为什么将值移动到闭包中仍然有错误消息 "cannot borrow immutable local variable as mutable"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53029622/

相关文章:

generics - 为什么我会收到错误 "Expected type parameter, found integral variable"?

rust - 从变量创建具有长度的空数组

rust - API 设计中的内部可变性滥用?

format - 以多个字符居中的 Rust 字符串

generics - 类型参数与 std::ops::BitXor 输出关联类型之间的类型不匹配

openssl - 错误 : native library `openssl` is being linked to by more than one version of the same package

rust - impl trait X for Y as Z 在 Substrate 的 decl_storage 宏中意味着什么?

rust - 奇怪的错误 : use of partially moved value

linked-list - 在 Rust 中使用 List<T>

rust - 什么是未初始化内存,为什么在分配时没有初始化?