For loop permanently borrows immutable vector?

Hey folks, I'm learning about the Rust language. One simple thing I'm trying to do is iterate over a Vec, in a for loop, and then access the Vec after the for loop.

let x = vec![5,6,17,2];

for val in x {
    println!("{}", val);
}
println!("{}", x[0]);

The above code yields the following error:

borrow of moved value: x value borrowed here after move

I figured by cloning the Vec with x.clone(), I could work around this.

let x = vec![5,6,17,2];

for val in x.clone() { // edited this line
    println!("{}", val);
}
println!("{}", x[0]);

This does work, but I'm confused at why the initial example fails. Why does x get borrowed by the for loop, but never given back to the parent scope?

for loops work with the IntoIterator trait. Vec's IntoIterator impl consumes the vec and iterates items by value. What you're looking for is

for x in vec.iter() {

}

Which iterates over items by reference.

Notice that every iterator automatically implements IntoIterator.

2 Likes

Perfect explanation. Thanks for helping me understand this better.

One can also write

for val in &x {
    println!("{}", val);
}

by the way, because &Vec<T> has it's own IntoIterator implementation. (Just like with explicit .iter(), val is a &i32 this way.)

4 Likes

To address the question itself: no, x is not borrowed. It is moved. Moving is the opposite of borrowing – it's destructive.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.