如何在遍历向量时改变其元素?

6

我正在遍历一个向量,想要改变其中的一个元素。

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

    for (i, el) in vector.iter().enumerate() {
        if i == 0 {
            continue;
        }
        vector[i - 1] += el
    }
}

这个错误提示是编译器报出的:

error[E0502]: cannot borrow `vector` as mutable because it is also borrowed as immutable
 --> src/main.rs:8:9
  |
4 |     for (i, el) in vector.iter().enumerate() {
  |                    ------ immutable borrow occurs here
...
8 |         vector[i - 1] += el
  |         ^^^^^^ mutable borrow occurs here
9 |     }
  |     - immutable borrow ends here

我理解为什么会出现这个错误。我将向量作为不可变对象借用到枚举范围内,并试图在该范围内修改内部,从而违反了借用规则。但我不明白如何正确做这件事。我猜我需要对枚举进行可变借用?
我尝试过各种组合,包括mut&mut,但每次都会遇到不同的编译器错误。我知道我可以将其设置为Vec<Cell<i32>>并以此方式修改内容,但对于这样一个简单的示例来说,这似乎有点过度设计了。

附注:还有 iter_mut - FObersteiner
1个回答

10
使用索引。
fn main() {
    let mut vector = vec![1, 2, 3, 4];

    for i in 1..vector.len() {
        vector[i - 1] += vector[i];
    }

    println!("{:?}", vector);
}

你可能会认为他们会有一个类似于chunks_mut函数的windows_mut函数,可以像windows一样方便地处理这个问题,但遗憾的是它并不存在。 - MutantOctopus
2
@BHustus: 他们不能。迭代器无法要求您在生成下一个元素之前放弃一个元素。对单个项目的可变引用没问题,因为您只能获得每个元素的一个 - DK.
2
更加建设性的注意事项是,与其使用if i == 0 { continue },使用起始值为1的遍历方式:for i in 1..vector.len()更符合惯用语法,除非在if块中需要进行更多操作。这也适用于提问中提供的原始示例。 - MutantOctopus
@BHustus:说得好。我通常尽可能精确地翻译这样的例子,以保持最少的更改……但是,是的,那种情况应该足够明显了。 - DK.
好的,这就是为什么我指定它也适用于原始示例的原因。我理解整个“保留示例”的问题。在这种情况下,我通常会将修改作为实际答案底部的附注添加进去。 - MutantOctopus
显示剩余5条评论

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