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

时间:2016-11-27 23:07:46

标签: rust

考虑以下(哑)程序:

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

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

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

error[E0384]: re-assignment of immutable variable `value`

&mut这里是否为no-op?

2 个答案:

答案 0 :(得分:8)

所以这里发生了一些不同的事情。首先,这里是答案:

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

因此。你哪去哪儿了?让我们看看value是什么,就像这样:

for &mut value in array {
    let () = value;
}

这会出现此错误:

  = note: expected type `u8`
  = note:    found type `()`

所以在这里,valueu8。但为什么?好吧,让我们试试这个:

for value in array {
    let () = value;
}

这给出了:

  = note: expected type `&mut u8`
  = note:    found type `()`

所以,value这里是&mut u8,是对数组的引用。所以,通过说for &mut value,我们说"嘿,这将成为指向u8的可变指针。我们希望value成为u8指出的值。这是因为&mut value模式,它与&mut T绑定并将value绑定到T

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

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

这......编译!我们完了吗?好吧,让我们试着打印array,以确保:

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

    println!("{:?}", array);
}

无法编译:

error[E0382]: use of moved value: `array`
 --> <anon>:7:22
  |
3 |     for value in array {
  |                  ----- value moved here

我们通过迭代销毁array。为什么?好吧,当你循环这样的数组时,你说你想要按主人循环。但那实际上是我们想要的;我们想通过可变引用循环。

Arrays有一种方法可以帮助解决这个问题:

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

    println!("{:?}", array);
}

iter_mut将按&mut T而不是T进行迭代。这样可行!

最后一件事:

let mut array = &mut [1u8, 2u8, 3u8];

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

let mut array = [1u8, 2u8, 3u8];

现在你来看我们的第一个代码示例。

希望这有帮助!

答案 1 :(得分:1)

  

&mut这里是否为no-op?

不,这是模式的一部分。 Print the type of value

fn main() {
    let mut array = &mut [1u8, 2u8, 3u8];

    for &mut value in array {
        let () = value;
        // expected type `u8`
    }

    for value in array {
        let () = value;
        // expected type `&mut u8`
    }
}