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?
A for loop's expression in Rust is an iterator that returns a series of values. Each element is one iteration of the loop. This value is then bound to variable and can be used inside the loop code to perform operations.
To iterate over items of a vector in R programming, use R For Loop. For every next iteration, we have access to next element inside the for loop block.
Rust supports four loop expressions: A loop expression denotes an infinite loop. A while expression loops until a predicate is false. A while let expression tests a pattern.
The break control statement allows us to stop the execution of a loop, break out of its iteration cycle and continue on to any code after it. To use the break control statement, we simply write the break keyword where we want to break out of the loop.
There are two problems with your code. Luckily, both of them can be solved by changing one thing. The problems are:
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
.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With