this is my first post on here, and I'm wondering about a good rust implementation with traits on enum types. I want to know if using an enum w/ a trait as a generator of different code is viable like the one below? Also a couple of things I'm curious about is if there is an overhead with the match statement? Would implementing separate structs be faster?
struct GeneralCell {
repr: char,
position: Position,
cell_type: Cell,
}
trait InitializeCells {
fn new(&self, position: Position) -> GeneralCell;
}
pub enum Cell {
Hall,
Filled,
Empty,
}
impl InitializeCells for Cell {
fn new(&self, position: Position) -> GeneralCell {
match self {
Cell::Hall => GeneralCell {
repr: 'H',
position,
cell_type: Cell::Hall,
},
Cell::Empty => GeneralCell {
repr: 'E',
position,
cell_type: Cell::Empty,
},
Cell::Filled => GeneralCell {
repr: 'F',
position,
cell_type: Cell::Filled,
},
}
}
}
1 Answer 1
I think there are two ways I would consider implementing this:
Using an enum
This is usually the appropriate design, in particular when you know all possible types up front. A benefit is the strong type checking, as you will be warned if a match
forgets to handle a particular type.
pub enum Cell {
Hall,
Filled,
Empty,
}
impl Cell {
pub fn get_char(&self) -> char {
match self {
Self::Hall => 'H',
Self::Filled => 'F',
Self::Empty => 'E',
}
}
}
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=eff909882165138262a103e5d075f1f1
Using a trait
This is a more flexible design, and allows you to more easily add new cell types later. You can also more easily add custom behaviour to cells. However, you now have to use trait objects, e.g. by storing the cell type as Box<dyn Cell>
.
pub trait Cell {
// If the char only depends on the type of cell, you can remove the `&self`.
fn get_char(&self) -> char;
}
struct Hall;
impl Cell for Hall {
fn get_char(&self) -> char {
'H'
}
}
struct Filled;
impl Cell for Filled {
fn get_char(&self) -> char {
'F'
}
}
struct Empty;
impl Cell for Empty {
fn get_char(&self) -> char {
'E'
}
}
Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=c5fdd7e1669814f3db04eacd9f43fa1b
impl
the method directly? Note that design-level questions are on-topic here, but if you're more interested in code-level help. Stack Overflow would be the better address.