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?