了解循环中的不可变借用

Understanding immutable borrows in loops

我不太明白为什么会这样编译:

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() 时)。

因此,我的预期是第一个片段不应该编译——当存在不可变借用时,我们在进行赋值时进行可变借用。

我误会了什么?

在第一种情况下,你实际上并没有进行不可变借用,或者更确切地说,它在调用 len() returns 之后结束(因为 len returns a原始类型不持有对其使用对象的引用)。这意味着您的循环非常好,因为您拥有唯一的可变对象。

在第二个上,您正在创建一个实现 Iterator<Item = &u32> 的类型,然后在该迭代器上进行迭代。迭代器对你的集合有一个不可变的借用(否则你怎么能在它上面调用 next() 呢?)。这有点隐藏,但这就是不可变借用的地方,也是你不能做你所做的事情的原因。

通常,在使用迭代器时,以及当您需要修改正在迭代的元素时,iter_mut 是可行的方法,原因很明显:-)