I'm just getting started with Rust and am running into an issue that's leaving me scratching my head.
I am programming the Game of Life and using the Cursive crate to render a visualization in the terminal.
The issue I'm running into is that I'm trying to pass in an instance of the game grid to the display_curses_grid
function that renders the grid and also adds a Cursive global callback (closure) that advances the grid and redraws it when a key is pressed. My code compiles and runs fine when the grid is instantiated (as mut
) in the display_curses_grid
function, but I run into a serious wrestling match with the compiler when I try to refactor my code so that the display function accepts the grid to display.
Here are the relevant functions:
type Grid = Vec<Vec<bool>>;
fn main() {
let mut siv = Cursive::default();
siv.add_global_callback('q', |s| s.quit());
display_curses_grid(&mut siv);
siv.run();
}
fn display_curses_grid(siv: &mut cursive::Cursive) {
let mut grid = make_default_grid();
siv.add_layer(
Dialog::new()
.title("Game of Life")
.padding((2, 2, 1, 1))
.content(LinearLayout::vertical().child(BoardView::new(grid.to_vec()))),
);
siv.add_global_callback('n', move |s| {
grid = tick(grid.to_vec());
s.pop_layer();
s.add_layer(
Dialog::new()
.title("Game of Life")
.padding((2, 2, 1, 1))
.content(LinearLayout::vertical().child(BoardView::new(grid.to_vec()))),
);
});
}
pub fn tick(grid: Grid) -> Grid {
let len = grid[0].len();
let mut new_grid = vec![vec![false; len]; len];
for y in 0..len {
for x in 0..len {
let data = neighbor_data(x as i32, y as i32, &grid);
new_grid[y][x] = match data {
(alive, _, true) if alive < 2 => false,
(alive, _, true) => alive == 2 || alive == 3,
(alive, _, false) => alive == 3,
};
}
}
new_grid
}
When I change the code so that main
instantiates the grid and change the display_curses_grid
function to accept a second grid
parameter, I run into some difficulty and so far haven't been able to figure out what to change to get the compiler happy.
Initially I tried instantiating the grid in main
and adding the grid: &mut Grid
as the 2nd param to display_curses_grid
, but that results in a mismatched types error "expected mutable reference, found struct std::vec::Vec
", as described in this commit: Try passing mut Grid reference to `display_curses_grid` · bantic/game_of_life_rust@c5306d7 · GitHub
If I accept the compiler's suggestion of mutably borrowing the grid.to_vec()
I get the new error "lifetime static
required". Here's the commit along with its new compiler error:
https://github.com/bantic/game_of_life_rust/commit/d8484f55ac1b3720ccd65f3d8351283f60971d4b
Can anyone help explain to me how I could do the refactoring I'm looking to do, and/or explain what these errors are describing?
Thank you!