Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding immutable borrows in loops

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?

like image 759
nz_21 Avatar asked Sep 05 '26 04:09

nz_21


1 Answers

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 :-)

like image 68
Sébastien Renauld Avatar answered Sep 08 '26 07:09

Sébastien Renauld



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!