我正在阅读Rust Book的第二版,我在迭代器部分找到了以下示例:
let v1 = vec![1, 2, 3];
let v1_iter = v1.iter();
for val in v1_iter {
println!("Got: {}", val);
}
为什么编译器不抱怨v1_iter
是不可变的?该书说for循环取得了v1_iter
的所有权并使其在幕后变得可变,但是你能将一个不可变变量转换为可变变量吗?
答案 0 :(得分:12)
这本书说for循环取得了v1_iter的所有权,并使其在幕后变得可变,
确切地说,人们可以做一个更简单的例子:
let v = vec![1,2,3];
let mut x = v;
x.push(0);
请注意v
和x
是单独的变量绑定:只要变量v
保留了我们的3元素向量,变量的约定就是向量不会变异。但是,向量被移动到x
,这表明可变性是可以接受的。这同样适用于函数调用:
fn foo(mut x: Vec<i32>) {
x.push(0);
}
let v = vec![1,2,3];
foo(v);
这是安全的,因为只有一个变量在其生命周期的任何一点拥有该向量。将v
移至x
后,将无法再使用v
。同样,在您的代码中,for循环后无法再使用v1_iter
。
但是你可以将一个不可变的变量转换成可变的吗?
两个片段都有效,因为该值已移至声明为mut
的新变量。但是,一旦变量被声明为不可变(或可变),该变量在其所有生命周期内都保持不变,并且无法更改。所以答案是否定的,但是所有权语义允许在具有不同可变性保证的变量之间移动值。
另见: