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!
From
trait, as mentioned by the compiler, or useBox::downcast
to attempt to extract aNumber
from aBox<dyn Expression
. – BrianFrom
trait right now and still dont understand how to extractNumber
that 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. } } } ` – georgieFrom
only makes sense if everyExpression
can be converted to a Number. Is this true for your design? Bear in mind, there is nothing stopping you from implementingExpression
for, say,Vec
. All yourFrom
implementation knows is thatexpr
is anExpression
trait object, which could be any type. Traits may be the wrong abstraction for what you are trying to accomplish. – Brianfn value (&self) -> i32
method to yourExpression
trait, then implement the proper behaviour forSum
andNumber
. – Jmb