Help with referencing in `for` loop

for e in vec { } // e: size. All consumed.

for e in &vec { } // e: &usize. Immutable references.
for &e in &vec { } // e: usize. Eg: Use e as an index without dereferencing.

for e in &mut vec { } // e: &mut usize. Mutable references. Eg: *e = 9.
for &mut e in &mut vec { e = 5; } // e: usize.

In the last case I'm trying to do something like e = 9 without dereferencing but I get an error:

10 |     for &mut e in &mut vec { e = 5; } // e: usize.
   |              -               ^^^^^ cannot assign twice to immutable variable
   |              |
   |              first assignment to `e`
   |              help: consider making this binding mutable: `mut e`

I understand for &e in &vec { } where i can use e without dereferencing and without getting consumed.

If your goal is that e = 9 will actually modify the entry in the original Vec, then that won't work. The pattern matching in for &mut e in &mut vec results in e being merely a copy read from the original usize in the vector. To modify the item inside of the vector, there's no way to avoid working with the reference and writing *e = 9 at the use site.

If your goal was to merely modify this copy, it's questionable that the iteration was by-mutable-reference in the first place (immutable reference would have been sufficient), but it is doable via the (slightly unwieldy) syntax &mut mut e in the pattern, i. e. for &mut mut e in &mut vec. If you want a mutable copy of a value read from an immutable reference, you can also write for &(mut e) in &vec. Note the parentheses for disambiguation, so this pattern doesn't mean "dereference a mutable reference" but it means "dereference an immutable reference, and make the resulting variable e (which will contain a copy of the entry) mutable".

6 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.