1

I am trying to modify a mutable sums: Vec<i64> while iterating over it. The loop code is as follows:

for (j, &mut sum) in sums.iter_mut().enumerate() {
    if !(j == i) {
        sum += n;
    }
}

And here is the error I get:

error[E0384]: re-assignment of immutable variable `sum`
  --> mini_max_sum.rs:27:17
   |
25 |         for (j, &mut sum) in sums.iter_mut().enumerate() {
   |                      --- first assignment to `sum`
26 |             if !(j == i) {
27 |                 sum += n;
   |                 ^^^^^^^^ re-assignment of immutable variable

This seems totally arcane to me. Rust lets me mutably borrow sum from sums, but the compiler prevents me from actually modifying it. Omitting .enumerate() does not even alter the resulting error code.

I would like to know how to fix the loop.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Mike Land
  • 436
  • 4
  • 15

1 Answers1

5

I don't know why you decided to add &mut to the pattern for the loop variable, but that's the problem. You need to take the mutable reference directly and then dereference it when you increment it:

fn main() {
    let mut sums = vec![1, 2, 3];
    let i = 0;
    let n = 0;

    for (j, sum) in sums.iter_mut().enumerate() {
        if j != i {
            *sum += n;
        }
    }
}

With &mut in the pattern, you are actually destructuring the variable and removing the mutable reference. If you print the type of your sum variable, you'll see that it's an i64.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • I didn't get it. What exactly is wrong with `&mut sum`? That seems to make more sense to me. Even I wrote that ending up with the same error. Now when you write just `sum`, that makes it immutable and copied, right? I want the reference to the object so that I can modify it, so I wrote `&mut sum`. Please explain why is that wrong? – Nawaz Sep 30 '18 at 04:53
  • 1
    @Nawaz In a pattern, the structure that is matched is removed. For example, in `Some(foo)` the `Some` wrapper is removed, leaving `foo` bound to the value inside. The same happens with `&` or `&mut` in a pattern. – Shepmaster Oct 07 '18 at 15:54