I can't quite understand why this compiles:
fn main() {
let mut v = vec![1,2,3];
for i in 1..v.len() {
v[i] = 20;
}
}
...and this doesn't:
fn main() {
let mut v = vec![1,2,3];
for (i,_) in v.iter().enumerate() {
v[i] = 20;
}
}
Error:
error[E0502]: cannot borrow `v` as mutable because it is also borrowed as immutable
--> src/main.rs:6:13
|
4 | for (i,_) in v.iter().enumerate() {
| --------------------
| |
| immutable borrow occurs here
| immutable borrow later used here
5 |
6 | v[i] = 20;
| ^ mutable borrow occurs here
In both cases we make an immutable borrow (one when call len(), other when we call iter()).
Thus, my expectation was that the 1st snippet should NOT compile -- we're making an mutable borrow when doing the assignment, when an immutable borrow exists.
What am I misunderstanding?
You are not actually making an immutable borrow in the first case, or rather, it ends after the call to len() returns (as len returns a primitive type not holding a reference to what it was used on). This means that your loop is perfectly fine, since you hold the one and only mutable object.
On the second one, you are creating a type that implements Iterator<Item = &u32> and then iterating on that iterator. The iterator has an immutable borrow to your collection (how else could you call next() on it otherwise?). This is a bit hidden, but that's where the immutable borrow is and why you cannot do what you did.
Typically, when working with iterators, and when you need to modify an element being iterated on, iter_mut is the way to go, for obvious reasons :-)
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