我不太明白为什么会这样编译:
fn main() {
let mut v = vec![1,2,3];
for i in 1..v.len() {
v[i] = 20;
}
}
...但不是:
fn main() {
let mut v = vec![1,2,3];
for (i,_) in v.iter().enumerate() {
v[i] = 20;
}
}
错误:
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:6:13
|
4 | for (i,_) in v.iter().enumerate() {
| --------------------
| |
| immutable borrow occurs here
| immutable borrow later used here
5 |
6 | v[i] = 20;
| ^ mutable borrow occurs here
在两种情况下,我们都是不可变的借贷(一种是在调用len()
时借用,另一种是在我们调用iter()
时借用)。
因此,我的期望是不应该编译第一个代码段-当存在不可变的借位时,我们在进行分配时要进行可变的借位。
我误会什么?
答案 0 :(得分:7)
在第一种情况下,您实际上并不是在进行一成不变的借用,或者说,它在对len()
的调用返回后终止(因为len
返回的原始类型不包含对其的引用使用)。这意味着您的循环非常完美,因为您拥有一个唯一的可变对象。
在第二个上,您要创建一个实现Iterator<Item = &u32>
的类型,然后在该迭代器上进行迭代。迭代器对您的集合有不可变的借用(否则您怎么能对它调用next()
?)。这有点隐蔽,但这就是不变的借贷所在,以及为什么您不能做自己做的事情。
通常,在使用迭代器时,当您需要修改要迭代的元素时,iter_mut
是显而易见的原因:-)