2026-09-13
eval_expr.rs
enum Expr {
Num(i64),
Add(Box<Expr>, Box<Expr>),
Mul(Box<Expr>, Box<Expr>),
}
fn eval(e: &Expr) -> i64 {
// write this: evaluate the expression tree
}
たとえば(2 + 3) * 4を表す木に対して20を返すように、evalを実装してください。
Reference
fn eval(e: &Expr) -> i64 {
match e {
Expr::Num(n) => *n,
Expr::Add(a, b) => eval(a) + eval(b),
Expr::Mul(a, b) => eval(a) * eval(b),
}
}
matchのアームがenumのバリアントと1対1に並び、型の定義の形がそのまま関数の形になります。&Exprに対するマッチなのでnは&i64(だから*n)、aとbは&Box<Expr>に束縛されますが、eval(a)に渡すと参照外し型強制で&Exprになるので、Boxを意識する必要はありません。所有権は動かず、木を借りたまま読むだけです。後からSubのようなバリアントを足すと、このmatchが網羅的でなくなってコンパイルエラーになり、直すべき場所をコンパイラが教えてくれます。これは参考実装であり、唯一の正解ではありません。