In my implementation of Conway's Game of Life in Rust, I've walked into a problem. I want to remember the previous state of the world. For this I've created an extra property on my Universe
struct, which now looks like this:
pub struct Universe {
width: usize,
height: usize,
cells: Vec<Cell>,
previous_cells: Option<Vec<Cell>>,
}
The Option
is there because at initialization, there is no previous state.
My idea would be that on every tick, we write the new state to the vector with the previous state. At the end, I swap the vectors. This resulted in the following code:
pub fn tick(&mut self) {
// get the previous state or create new one if it doesn't exist (i.e. this is the first tick/update)
let mut next = match self.previous_cells {
Some(cells) => cells,
None => {
let mut new_vec = Vec::with_capacity(self.width() * self.height());
new_vec.resize(new_vec.capacity(), Cell::Dead);
new_vec
}
};
// Calculate next state, not relevant for question
for row in 0..self.height as isize {
for column in 0..self.width as isize {
let index = self.get_index(row , column);
let target_cell = self.cells[index];
let live_neighbors = self.live_neighbor_count(row, column);
next[index] = match target_cell {
Cell::Alive => if live_neighbors == 2 || live_neighbors == 3 { Cell::Alive } else { Cell::Dead }
Cell::Dead => if live_neighbors == 3 { Cell::Alive } else { Cell::Dead }
}
}
}
// swap values
self.previous_cells = Some(self.cells);
self.cells = next;
}
Now I get the following errors from the compiler:
error[E0507]: cannot move out of `self.previous_cells.0` which is behind a mutable reference
--> src/lib.rs:61:30
|
61 | let mut next = match self.previous_cells {
| ^^^^^^^^^^^^^^^^^^^ help: consider borrowing here: `&self.previous_cells`
62 | Some(cells) => cells,
| -----
| |
| data moved here
| move occurs because `cells` has type `std::vec::Vec<Cell>`, which does not implement the `Copy` trait
error[E0507]: cannot move out of `self.cells` which is behind a mutable reference
--> src/lib.rs:83:36
|
83 | self.previous_cells = Some(self.cells);
| ^^^^^^^^^^ move occurs because `self.cells` has type `std::vec::Vec<Cell>`, which does not implement the `Copy` trait
I get why this happens, but I don't see a solution that does not include copying the entire Vec. That would be a solution, but is there maybe a better one?