在声明for循环变量时,&mut会做什么吗?

Cor*_*lks 2 rust

考虑以下(哑)程序:

fn main() {
    let mut array = &mut [1u8, 2u8, 3u8];
    for &mut value in array {
    }
}
Run Code Online (Sandbox Code Playgroud)

它编译并运行正常(虽然警告未使用的变量/不必要的可变性,如预期的那样).但是&mutfor声明中做了什么?

它似乎没有给你一个可变的数组引用,因为尝试value = 0;在错误中分配结果:

error[E0384]: re-assignment of immutable variable `value`
Run Code Online (Sandbox Code Playgroud)

这是&mut一个无操作吗?

Ste*_*nik 8

所以这里有一些不同的东西.首先,这是答案:

fn main() {
    let mut array = [1u8, 2u8, 3u8];
    for value in &mut array {
        *value = 0; 
   }
}
Run Code Online (Sandbox Code Playgroud)

所以.你哪去哪儿了?让我们来看看是什么value,像这样:

for &mut value in array {
    let () = value;
}
Run Code Online (Sandbox Code Playgroud)

这给出了这个错误:

  = note: expected type `u8`
  = note:    found type `()`
Run Code Online (Sandbox Code Playgroud)

所以在这里,value是一个u8.但为什么?好吧,让我们试试这个:

for value in array {
    let () = value;
}
Run Code Online (Sandbox Code Playgroud)

这给出了:

  = note: expected type `&mut u8`
  = note:    found type `()`
Run Code Online (Sandbox Code Playgroud)

所以,value这是一个&mut u8对数组的引用.所以说for &mut value,我们说"嘿,这将是一个指向a的可变指针u8.我们希望value成为u8指向的价值.这是因为&mut value是一种模式,它与a &mut T绑定并绑定valueT.

所以,我们删除了&mut,因为我们不想要值的副本,我们想用它来修改指向的内容.所以看起来像这样:

fn main() {
    let mut array = &mut [1u8, 2u8, 3u8];
    for value in array {
        *value = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

这......编译!我们完了吗?好吧,让我们试着打印出来array,只是为了确定:

fn main() {
    let mut array = &mut [1u8, 2u8, 3u8];
    for value in array {
        *value = 0;
    }

    println!("{:?}", array);
}
Run Code Online (Sandbox Code Playgroud)

这无法编译:

error[E0382]: use of moved value: `array`
 --> <anon>:7:22
  |
3 |     for value in array {
  |                  ----- value moved here
Run Code Online (Sandbox Code Playgroud)

我们已经array被迭代破坏了.为什么?好吧,当你像这样循环一个数组时,你说你想要按主人循环.但这实际上并不是我们想要的; 我们想通过可变引用循环.

数组有一个方法可以帮助解决这个问题:

fn main() {
    let mut array = &mut [1u8, 2u8, 3u8];
    for value in array.iter_mut() {
        *value = 0;
    }

    println!("{:?}", array);
}
Run Code Online (Sandbox Code Playgroud)

iter_mut将迭代&mut T而不是T.这样可行!

但最后一件事是:

let mut array = &mut [1u8, 2u8, 3u8];
Run Code Online (Sandbox Code Playgroud)

这说明array是一个&mut [u8; 3],即对数组的可变引用,而不是数组本身.这可能不是你真正想要的,而且它不是我们的代码所必需的.所以我们可以删除&mut一下:

let mut array = [1u8, 2u8, 3u8];
Run Code Online (Sandbox Code Playgroud)

现在,您将获得我们的第一个代码示例.

希望这可以帮助!