Reputation: 7837
I'm trying to learn rust from the tutorial. I thought Conway's game of life would be a good place to start.
I'm having trouble understanding how to write this Grid::new() fn.
Here's what I have so far:
enum Cell {
alive, dead
}
impl Cell {
fn new() -> Cell {
alive
}
struct Grid {
priv inner: [ [Cell, .. GRID_SIZE], .. GRID_SIZE],
}
impl Grid {
fn new() {
Grid { inner: ???? }
}
}
...
fn main () {
let grid = Grid::new(); // Stack allocated grid (internal stack allocad array)
}
What I want is for the grid to be initialized with cells all of the value 'alive'.
Upvotes: 7
Views: 8037
Reputation: 3551
Grid::new
should initialize Grid::inner
with a nested fixed-size array literal, which is written just like the type, but with the value you want to initialize your array with in place of the Cell
type:
impl Grid {
fn new -> Grid {
Grid { inner: [[alive, ..GRID_SIZE], ..GRID_SIZE] }
}
}
(You can use Cell::new()
instead of alive
if you'd rather use the constructor function.)
The inner
member can then be used in expressions as follows (note that priv
only controls visibility to code outside the current module):
let grid = Grid::new();
let nested_fixed_sized_array: [[Cell, ..GRID_SIZE], ..GRID_SIZE] = grid.inner;
let fixed_sized_array: [Cell, ..GRID_SIZE] = grid.inner[0];
let cell_element: Cell = grid.inner[0][0];
In Rust, nested arrays, as used in this example, are a special case of fixed-size arrays.
To see how this works, see the tutorial section on Vectors and Strings. In particular, unlike vectors (of type ~[T]
), which are dynamically allocated on the heap and can change their length (if they're mutable), fixed-size arrays have their length embedded in the type ([T, ..LENGTH]
), so that they can't change size after being created. T
itself must be either a fixed-size type or a pointer. In exchange, however, fixed-size arrays are value types that can be directly allocated on the stack, embedded in struct
definitions (like Grid
), etc.
Since a fixed-size array is itself a fixed-size type, a nested fixed-size array is just a special case where a fixed-size array is the element type of a fixed-size array. In particular, the memory taken up by Grid::inner
is exactly GRID_SIZE * GRID_SIZE * sizeof(Cell)
(if we ignore alignment). Also useful is a vector of fixed-size arrays ~[T, ..LENGTH]
, when you know the number of columns in a matrix but not the number of rows.
Both vectors and fixed-size arrays can serve as a function argument if the argument is a slice (type &[T]
).
Some details may change between now and the release of Rust 1.0. If you're curious, searching the Rust subreddit for "dynamically sized types" should turn up the proposed changes and the reasoning behind them, or you can always ask around on Reddit or the #rust IRC channel.
Upvotes: 8