This week I learned 16 — late post
Destructuring
I lot of my programming is structuring and destructuring data. An interesting area for structuring data is enums. Rust allows three variant types: unit-like, tuple-like, and struct-like. rlox uses enums to represent valid lox expressions:
struct Token;
struct Object;
pub enum Expr<'a> {
Binary(Box<Expr<'a>>, &'a Token, Box<Expr<'a>>),
Grouping(Box<Expr<'a>>),
Literal(Object),
Unary(&'a Token, Box<Expr<'a>>),
}
Matching on this enum is easy too:
let e = Expr::Literal(Object);
match e {
Expr::Binary(left, token, right) => {}
Expr::Grouping(group) => {}
Expr::Literal(object) => {}
Expr::Unary(token, right) => {}
}
When I first wrote the code for rlox's
Expr
implementation, I created
separate structs for each variant (that needed one).
struct Token;
struct Object;
enum Expr<'a> {
Binary(Binary<'a>),
Grouping(Grouping<'a>),
Literal(Object),
Unary(Unary<'a>),
}
struct Binary<'a> {
left: Box<Expr<'a>>,
token: &'a Token,
right: Box<Expr<'a>>,
}
struct Grouping<'a> {
grouping: Box<Expr<'a>>,
}
struct Unary<'a> {
token: &'a Token,
right: Box<Expr<'a>>,
}
This is a lot more code and adds another level of indirection while matching:
let e = Expr::Literal(Object);
match e {
Expr::Binary(b) => {}
Expr::Grouping(group) => {}
Expr::Literal(object) => {}
Expr::Unary(u) => {}
}