为什么编译器不抱怨移动到 for 循环的迭代器是不可变的?

Why does the compiler not complain that an iterator moved to a for loop is immutable?

我正在阅读 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 的所有权并使其在幕后可变,但是您可以将不可变变量转换为可变变量吗?

The book says the for loop took ownership of v1_iter and made it mutable behind the scenes,

没错,还有一个更简单的例子:

let v = vec![1,2,3];
let mut x = v;
x.push(0);

请注意 vx 是单独的变量绑定:只要变量 v 保留我们的三元素向量,变量的契约就是向量不会变异。但是,矢量已移至 x,这表明可变性是可以接受的。这同样适用于函数调用:

fn foo(mut x: Vec<i32>) {
    x.push(0);
}

let v = vec![1,2,3];
foo(v);

这是安全的,因为只有一个变量在其生命周期的任何时候拥有向量。一旦 v 被移动到 xv 就不能再使用了。同样,在您的代码中,v1_iter 不能再在 for 循环之后使用。

but can you convert an immutable variable to mutable?

这两个代码段都有效,因为该值已移至声明为 mut 的新变量。但是,一旦变量被声明为不可变(或可变),该变量在其整个生命周期内都保持不变,并且无法更改。所以答案是否定的,但是所有权语义允许在具有不同可变性保证的变量之间移动值。

另请参阅: