了解循环中的不可变借位

nz_*_*_21 3 rust borrow-checker

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

fn main() {
    let mut v = vec![1,2,3];

    for i in 1..v.len() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

...而这不是:

fn main() {
    let mut v = vec![1,2,3];

    for (i,_) in v.iter().enumerate() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

fn main() {
    let mut v = vec![1,2,3];

    for i in 1..v.len() {
            v[i] = 20;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我们都是不可变的借用(一个在调用时len(),另一个在调用时iter())。

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

我有什么误会?

Séb*_*uld 7

在第一种情况下,您实际上并不是在进行不可变的借用,或者说,它在对return的调用之后终止len()(因为len返回的原始类型不保存对其使用的引用)。这意味着您的循环非常好,因为您拥有一个唯一的可变对象。

在第二个上,您要创建一个实现的类型,Iterator<Item = &u32>然后在该迭代器上进行迭代。迭代器对您的集合有不可变的借用(否则您还可以调用next()它吗?)。这有点隐蔽,但这就是不变的借口所在,也是为什么您不能做自己所做的事情。

通常,在使用迭代器时,以及当您需要修改要迭代的元素时iter_mut,出于明显的原因,这是要走的路:-)