我什么时候应该关闭mut?

Faj*_*iya 0 closures mutable mutability rust

假设我有这个代码:

let mut s = "hi".to_string();
let c = || s.push_str(" yo");
c();
Run Code Online (Sandbox Code Playgroud)

它不会编译并生成此错误:

error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable                 
   --> src\test.rs:120:9
    |
119 |         let c = || s.push_str(" yo");
    |             -      - calling `c` requires mutable binding due to mutable borrow of `s`  
    |             |
    |             help: consider changing this to be mutable: `mut c`
120 |         c();
    |         ^ cannot borrow as mutable

For more information about this error, try `rustc --explain E0596`.
error: could not compile `test` due to previous error
Run Code Online (Sandbox Code Playgroud)

为什么c();不能借用可变的?它不能借用什么是可变的?c?为了使其工作,我必须将其更改为:

let mut s = "hi".to_string();
let mut c = || s.push_str(" yo");
c();
Run Code Online (Sandbox Code Playgroud)

但在这里我只是定义一个closure c。我不会修改它,比如c = || x;。为什么必须将其定义为let mut c

Mas*_*inn 5

但在这里我只是定义一个closure c。我不会修改它,比如c = || x;。为什么必须将其定义为 let mut c

因为闭包本质上是一个结构,每个捕获的项目都是该结构的成员。

所以你的代码大致相当于这样:

struct S<'a>(&'a mut String);
impl S<'_> {
    fn call(&mut self) {
        self.0.push_str("yo");
    }
}
fn main() {
    let mut s = "hi".to_string();
    let c = S(&mut s);
    c.call();
}
Run Code Online (Sandbox Code Playgroud)

并且无法编译,并出现或多或少相同的错误:

error[E0596]: cannot borrow `c` as mutable, as it is not declared as mutable
  --> src/main.rs:14:5
   |
13 |     let c = S(&mut s);
   |         - help: consider changing this to be mutable: `mut c`
14 |     c.call();
   |     ^^^^^^^^ cannot borrow as mutable
Run Code Online (Sandbox Code Playgroud)

现在您可能会反对这是因为我定义了fn call(&mut self),但如果您不这样做,您会得到相同错误的内部部分:

error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
 --> src/main.rs:8:9
  |
7 |     fn call(&self) {
  |             ----- help: consider changing this to be a mutable reference: `&mut self`
8 |         self.0.push_str("yo");
  |         ^^^^^^^^^^^^^^^^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
Run Code Online (Sandbox Code Playgroud)

也就是说你不能通过 an 修改&mutan &。因为如果你这样做了,你可以创建多个&相同的 s,&mut通过它你可以修改被指点,这实际上会给你多个&mut.

Rust 的语义不允许这样做:

在任何给定时间,您可以拥有一个可变引用或任意数量的不可变引用。