考虑以下(哑)程序:
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?
答案 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 `()`
所以在这里,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
是模式,它与&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`
}
}