简体   繁体   中英

How do I declare a type as "one of an enum variant or a None"?

I simplified the problem to this situation. Imagine classic tic-tac-toe / tris game.

Players can use X or O.

pub enum Symbol {
    X,
    O,
}

When thinking about a cell content, one of the 9 positions where user can play, I think, in human terms as

  • a cell can contain a Symbol::X , a Symbol::O or a None (when it's not played yet)

How can I represent this content as a type/enum/struct?

Is this a case where we can use Generics? or dynamics? What is the syntax?

Option 1

pub enum CellContent {
    Move(Symbol),
    None,
}

Option 2

pub type CellContent = Option<Symbol>;

Option 3 (from accepted answer)

Scale the problem to the above structure, defining something like an Option<Symbol>

Personal note

the option 2, being a type, bring the disvantage that we cannot implement functions fir this type, so we cannot use it because we need compare, etc..

You can place your Symbol enum inside an Option , ie: Option<Symbol> :

// your 3x3 table
let mut table: [[Option<Symbol>; 3]; 3] = Default::default();

Initially, all the cells in the table will be None . Then, playing:

table[1][1] = Some(Symbol::X);
table[1][2] = Some(Symbol::O);

Alternatively, you could follow an intrusive approach by defining Symbol instead as:

pub enum Symbol {
    NotPlayedYet,
    X,
    O,
}

That is, defining an additional variant Symbol::NotPlayedYet . For this case, you would probably want to implement Default for Symbol to default to Symbol::NotPlayedYet :

impl Default for Symbol {
    fn default() -> Self {
        Symbol::NotPlayedYet
    }
}

Play it this way:

let mut table: [[Symbol; 3]; 3] = Default::default();

table[1][1] = Symbol::X;
table[1][2] = Symbol::O;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM