我什么时候需要使闭包变量可变?

Muh*_*fil 2 closures rust

为什么我需要使这个闭包变量可变?闭包不返回任何内容,因此闭包变量中没有存储任何内容。这个闭包只是从环境中捕获一个值并递增它。

fn main() {
    let mut x = 1;
    let mut y = || x = x + 1;
    y();
    println!("{}", x);
}
Run Code Online (Sandbox Code Playgroud)

Sve*_*ach 8

本质上,这是 Rust 稳健性规则之一的结果——您不能通过对可变引用的共享引用来修改任何内容。引用链中的所有引用都必须是可变的,才能实现这一点。

让我们使用结构将示例中的闭包转换为大致等效的代码:

struct Closure<'a> {
    x: &'a mut i32,
}

impl Closure<'_> {
    fn call(&mut self) {
        *self.x += 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

闭包x通过可变引用捕获——它必须能够修改它。当闭包被调用时,它self通过可变引用接收——它必须能够x通过self指针进行变异。

现在如果你想调用这个闭包,你还需要让它可变:

let mut x = 1;
let mut y = Closure { x: &mut x };
y.call();
Run Code Online (Sandbox Code Playgroud)

如果不进行y可变,则无法将可变引用传递y给该call()方法。

开头提到的健全性规则的原因很容易看出:如果您可以通过对可变引用的共享引用进行变异,那么很容易编写多个玩家持有同一内存位置的可变引用的代码,这违反了一个关于 Rust 引用的基本规则。