This code:
use std::fmt;
use std::result::Result::{self, Ok, Err};
#[derive(Clone)]
#[derive(Copy)]
enum Tile {
White,
Black,
Empty
}
type Board = &[[Tile; 19]; 19];
Produces this error:
Compiling go v0.1.0 (file:///home/max/gits/go_rusty)
src/main.rs:12:14: 12:31 error: missing lifetime specifier [E0106]
src/main.rs:12 type Board = &[[Tile; 19]; 19];
^~~~~~~~~~~~~~~~~
error: aborting due to previous error
Could not compile `go`.
To learn more, run the command again with --verbose.
I'm having a hard time finding anything that explains what a lifetime specifier is and why I would need that on a type alias declaration.
The short answer is
type Board<'a> = &'a [[Tile; 19]; 19];
Rust is always explicit about generic arguments. Lifetimes also are generic arguments. Imagine you'd be generic over the Tile
type.
type Board = &[[T; 19]; 19];
This would cause an error about T
not existing (except if you defined an actual type named T
). But you'd like to be able to use Board
for any inner type. So what you'd need to do is to add a generic argument to the definition:
type Board<T> = &[[T; 19]; 19];
So whenever you use the Board
type alias, you also need to pass the T
type.
Back to our lifetime issue. Our type alias has a reference. We don't know what the lifetime of this reference is. The reason why you rarely need to specify a lifetime is lifetime-elision. This is one of the cases where you need to specify the lifetime, since you want the lifetime to be determined at all locations where you use Board
, like as if you used &[[Tile; 19]; 19]
everywhere directly. At the type alias definition the only available lifetime is 'static
, so we need to define a new generic one.