理解循环中的不可变借用

3

我不太明白为什么这段代码可以编译通过:

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

因此,我的期望是第一个代码片段不应该编译--当进行赋值时,我们正在进行可变借用,而存在不可变借用。

那么我有什么误解吗?

1个回答

8
在第一个情况下,实际上您并没有进行不可变借用,或者说,在调用len()返回后就结束了(因为len返回一个原始类型,并不持有对其使用的对象的引用)。这意味着,由于您只持有唯一的可变对象,因此您的循环是完全可以的。
在第二种情况下,您创建了一个实现了Iterator<Item = &u32>的类型,然后在该迭代器上进行迭代。迭代器对您的集合进行了不可变借用(否则您怎么能调用它的next()呢?)。这有点隐蔽,但这就是不可变借用的地方,也是您不能像以前那样做的原因。
通常,在使用迭代器时,如果需要修改正在迭代的元素,则可以使用iter_mut,原因显而易见 :-)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接