I've recently taken on learning Rust and I'm trying to write a small expression evaluator. I've been practicing Rust for a few days now and thought this task would be cool to work with Rust's Traits. What I tried to do is make Sum & Number structs implement Expression trait, so that I could express (pun unintended) (1 + 2) as an expression where left and right hand sides are expressions too. I've stumbled onto the problem that you can't just use Traits as properties' types, so you instead should use &dyn Trait or Box in the Book. Following this notion a rewrote it and now it compiles, but I can't get access to values inside Sum. Here's my code:
trait Expression {}
#[derive(Debug)]
struct Number {
pub val: i32
}
impl Expression for Number {}
struct Sum {
pub left: Box<dyn Expression>,
pub right: Box<dyn Expression>
}
impl Expression for Sum {}
fn main() {
let e = Sum{ left: Box::new(Number{ val: 2}),
right: Box::new(Number{ val: 2})
};
let sum = (2 + 2);
println!("{:#?}", sum);
}
What I want to be able to do is get to Number's value:
e.left.val
and use nested constuctions like:
Sum{Sum{Number, Sum{Number, Number}}, Number}
I also tried to make explicit cast to Number:
let val = (e.left as Number).val;
But it fails with an error:
non-primitive cast: std::boxed::Box<(dyn Expression + 'static)> as Number
note: an as expression can only be used to convert between primitive types. Consider using the From trait.
Sorry for any language mistakes or messy explanation, English is not my first language.
I'm not an experienced programmer and very new to Rust so I would really appreciate any help, thanks!
Fromtrait, as mentioned by the compiler, or useBox::downcastto attempt to extract aNumberfrom aBox<dyn Expression. - BrianFromtrait right now and still dont understand how to extractNumberthat lies inBox<dyn Expression>to construct newNumber. My code for this is: ` impl From<Box<dyn Expression>> for Number { fn from(expr: Box<dyn Expression>) -> Self { //? Number { val: expr. } } } ` - georgieFromonly makes sense if everyExpressioncan be converted to a Number. Is this true for your design? Bear in mind, there is nothing stopping you from implementingExpressionfor, say,Vec. All yourFromimplementation knows is thatexpris anExpressiontrait object, which could be any type. Traits may be the wrong abstraction for what you are trying to accomplish. - Brianfn value (&self) -> i32method to yourExpressiontrait, then implement the proper behaviour forSumandNumber. - Jmb