如何在向量中递增每个数字而不出现"无法同时借用为可变"错误?

3

这段代码的作用是将向量中的每个值加1:

fn main() {
    let mut v = vec![2, 3, 1, 4, 2, 5];
    let i = v.iter_mut();
    for j in i {
        *j += 1;
        println!("{}", j);
    }
    println!("{:?}", &mut v);
}

由于 Rust 的借用规则,它无法正常工作:
error[E0499]: cannot borrow `v` as mutable more than once at a time
 --> src/main.rs:8:27
  |
3 |     let i = v.iter_mut();
  |             - first mutable borrow occurs here
...
8 |     println!("{:?}", &mut v);
  |                           ^ second mutable borrow occurs here
9 | }
  | - first borrow ends here

我该如何完成这个任务?

嗯,对我来说,代码运行正常。 - Tomasz Waszczyk
4个回答

7
不要存储可变迭代器;直接在循环中使用它即可:
fn main() {
    let mut v = vec![2, 3, 1, 4, 2, 5];

    for j in v.iter_mut() { // or for j in &mut v
        *j += 1;
        println!("{}", j);
    }

    println!("{:?}", &v); // note that I dropped mut here; it's not needed
}

在第四行中,v.iter_mut() 的作用域是什么? - saga
@saga for 循环的主体部分。 - ljedrz
所以我们必须利用嵌套作用域来处理 Rust 的这个限制,我说得对吗? - saga
@saga 在这种循环情况下,我会说这只是传统和简单的方法,但总的来说,嵌套作用域可以解决不同的借用检查问题。 - ljedrz
我想说这只是传统而且简单的方式。还有其他可能的方法吗? - saga
1
@saga 当然可以;例如,您可以编写 for j in 0..v.len(),然后引用 v[j] 而不是 *j - ljedrz

3

由于非词法生命周期,您的代码将在未来版本的Rust中按原样工作:

#![feature(nll)]

fn main() {
    let mut v = vec![2, 3, 1, 4, 2, 5];
    let i = v.iter_mut();
    for j in i {
        *j += 1;
        println!("{}", j);
    }
    println!("{:?}", &mut v);
}

游乐场


0
在我看来,最简单和易读的解决方案是:
#![feature(nll)]
fn main() {
    let mut v = vec![2, 3, 1, 4, 2, 5];
    for i in 0..v.len() {
        v[i] += 1;
        println!("{}", j);
    }
    println!("{:?}", v);
}

0

你也可以使用mapcollect,例如:

>> let mut v = vec![5,1,4,2,3];
>> v.iter_mut().map(|x| *x += 1).collect::<Vec<_>>();
>> v
[6, 2, 5, 3, 4]

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