考虑以下(哑)程序:
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
是空操作吗?
最佳答案
所以这里发生了一些不同的事情。首先,这是答案:
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 `()`
所以在这里,value
是一个 u8
。但为什么?好吧,让我们试试这个:
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
是一个 pattern,它绑定(bind) &mut T
并将 value
绑定(bind)到 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
。为什么?好吧,当你像这样循环一个数组时,你是说你想按所有者循环。但这实际上不是我们想要的;我们想通过可变引用循环。
数组有一个方法可以帮助解决这个问题:
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];
现在您看到了我们的第一个代码示例。
希望这对您有所帮助!
关于rust - &mut 在声明 for 循环变量时有什么作用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40834969/