【问题标题】:How to mutate a vector's elements while iterating through it? [duplicate]如何在遍历向量时改变向量的元素? [复制]
【发布时间】:2018-03-29 04:06:08
【问题描述】:

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

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>> 并以这种方式改变内容,但对于这样一个简单的示例来说,这似乎有点过头了。

【问题讨论】:

    标签: rust


    【解决方案1】:

    使用索引。

    fn main() {
        let mut vector = vec![1, 2, 3, 4];
    
        for i in 1..vector.len() {
            vector[i - 1] += vector[i];
        }
    
        println!("{:?}", vector);
    }
    

    【讨论】:

    • 你会认为他们有一个 windows_mut 函数,比如 chunks_mut 而不是 windows,它可以很容易地处理这个问题,但是唉。
    • @BHustus:他们不能。迭代器不能要求您在生成下一个项目之前删除一个项目。对单个项目的可变引用很好,因为每个元素只能获得 one
    • 在更具建设性的注释上,而不是if i == 0 { continue },简单地从1 开始会更惯用:for i in 1..vector.len(),除非在该if 块中需要更多操作。这也适用于问题中提供的原始示例。
    • @BHustus:好点子。我通常会尽可能准确地翻译这样的示例,以保持最少的更改……但是,是的,希望这种情况足够明显。
    • 嗯,这就是为什么我指定它也适用于原始示例。我得到了整个“保持榜样”的问题。在这种情况下,我通常将修改添加为实际答案底部的附注。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-26
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多