Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

missing lifetime specifier [E0106] on type alias

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.

like image 410
mavix Avatar asked Jun 03 '15 03:06

mavix


Video Answer


1 Answers

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.

like image 136
oli_obk Avatar answered Nov 15 '22 11:11

oli_obk