How to run for loop on elements of a vector and change the vector inside the for loop and outside the for loop in rust?

耗尽温柔 提交于 2020-06-26 06:02:38

问题


I am new to Rust. I need to create a vector before a for loop. Run for loop on it. Change the vector inside the for loop. Then Change the vector after the for loop.

I tried the following code and tried to use immutable borrow but both did not work.

fn main() {
    let mut vec1 = vec![4, 5];
    vec1.push(6);
    for i in vec1 {
        if i % 2 == 0 {
            vec1.push(7);
        }
    }
    vec1.push(8);
    println!("vec1={:?}", vec1);
}

I expect to compile and change the vector inside and after the for loop. But it shows this error message:

error[E0382]: borrow of moved value: `vec1`
 --> src/main.rs:6:13
  |
2 |     let mut vec1 = vec![4, 5];
  |         -------- move occurs because `vec1` has type `std::vec::Vec<i32>`, which does not implement the `Copy` trait
3 |     vec1.push(6);
4 |     for i in vec1 {
  |              ----
  |              |
  |              value moved here
  |              help: consider borrowing to avoid moving into the for loop: `&vec1`
5 |         if i % 2 == 0 {
6 |             vec1.push(7);
  |             ^^^^ value borrowed here after move

Can you explain why move occurs? Can you make it compile?


回答1:


There are two problems with your code. Luckily, both of them can be solved by changing one thing. The problems are:

  • Writing for _ in vec1 moves the value vec1 into the loop. This is a move like every other move, meaning that the value is not accessible after the loop! If you need a refresher on ownership and moving, please read the related chapter in the Rust book. You can iterating over references to a vector's elements via for _ in &vec1.
  • You are trying to mutate the vector you are iterating over. Regardless of whether you iterate over the vector by value (as you do) or by reference, you cannot change the vector while iterating over it. And there are many good reasons for that! In your case, you could easily end up having an infinite loop if you add elements while iterating.

To solve both problems at the same time, you can iterate over indices to the vector instead of the vectors elements (Playground):

let mut vec1 = vec![4, 5];
vec1.push(6);
for i in 0..vec1.len() {
    if vec1[i] % 2 == 0 {
        vec1.push(7);
    }
}
vec1.push(8);
println!("vec1={:?}", vec1);

This way, the vector is not moved nor borrowed by the for loop and we are free to mutate it during and after the loop. This particular solution iterates over the indices of the original vector, meaning that elements added in the loop are not iterated over by the loop. This is a good protection to avoid accidental infinite loops. Please note, however, that you can still shoot yourself in the foot by, for example, removing elements from the vector during iteration. In general, independent of programming language, mutating collections while iterating over them is dangerous and should only be done with care.



来源:https://stackoverflow.com/questions/57637354/how-to-run-for-loop-on-elements-of-a-vector-and-change-the-vector-inside-the-for

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!