0

I am trying to loop over an array that contains mutable elements. For each element, except the first, I wish to mutate it based on the state of the previous element. Take this, for a toy example:

#[derive(Copy, Clone, Debug)]
struct Foo(u32);

impl Foo {
    fn new() -> Self {
        Foo(1)
    }
    
    fn frobnicate(&mut self, other: &mut Self){
        self.0 += other.0;
        other.0 += 1;
    }
}

fn main() {
    let mut array = [Foo::new(); 3];   // FIXME
    
    for i in 1..3 {
        let mut this = array[i];       // FIXME
        let last = &mut array[i - 1];  // FIXME
        
        this.frobnicate(last);
    }
    
    println!("{:?}", array);
}

The FIXME lines allow the above to compile, but it doesn't give the correct result. I would expect the following state:

         | Start  | i = 1  | i = 2  |
-------- | ------ | ------ | ------ |
array[0] | Foo(1) | Foo(2) | Foo(2) |
array[1] | Foo(1) | Foo(2) | Foo(3) |
array[2] | Foo(1) | Foo(1) | Foo(3) |

The final output I get is [Foo(2), Foo(2), Foo(1)]. I think this is happening because this is a mutable copy of array[i], rather than a mutable reference, which is just discarded at the end of each loop iteration. If I change to:

let this = &mut array[i];

Then I get a borrow error on the assignment of last. The compiler suggests .split_at_mut(position), but this is getting into the weeds of my understanding; moreover, this method (and .split_array_mut) are marked as experimental.

How can I independently mutate elements from the same array?

Xophmeister
  • 8,884
  • 4
  • 44
  • 87

0 Answers0