mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-20 06:21:09 +02:00
Remove error handling from expression evaluation exercise (#2517)
I think it would be good to simplify the expression evaluation exercise by removing the error handling around the divide-by-zero case. I think it overcomplicates the exercise and and adds confusion since at this point we haven't introduced `Result` (or at least not in any detail). This allows the students to just focus on writing the pattern matches on `Expression` and `Op`, and allows the exercise to be shorter (and I think we need to free up some time where we can, my classes often run long and cut into how much time students have for exercises).
This commit is contained in:
parent
f60513ebe2
commit
2bae363d16
@ -1,5 +1,5 @@
|
||||
---
|
||||
minutes: 30
|
||||
minutes: 20
|
||||
---
|
||||
|
||||
# Exercise: Expression Evaluation
|
||||
@ -57,11 +57,6 @@ the course. An expression can be "boxed" with `Box::new` as seen in the tests.
|
||||
To evaluate a boxed expression, use the deref operator (`*`) to "unbox" it:
|
||||
`eval(*boxed_expr)`.
|
||||
|
||||
Some expressions cannot be evaluated and will return an error. The standard
|
||||
[`Result<Value, String>`](https://doc.rust-lang.org/std/result/enum.Result.html)
|
||||
type is an enum that represents either a successful value (`Ok(Value)`) or an
|
||||
error (`Err(String)`). We will cover this type in detail later.
|
||||
|
||||
Copy and paste the code into the Rust playground, and begin implementing `eval`.
|
||||
The final product should pass the tests. It may be helpful to use `todo!()` and
|
||||
get the tests to pass one-by-one. You can also skip a test temporarily with
|
||||
|
@ -38,39 +38,27 @@ enum Expression {
|
||||
// ANCHOR_END: Expression
|
||||
|
||||
// ANCHOR: eval
|
||||
fn eval(e: Expression) -> Result<i64, String> {
|
||||
fn eval(e: Expression) -> i64 {
|
||||
// ANCHOR_END: eval
|
||||
match e {
|
||||
Expression::Op { op, left, right } => {
|
||||
let left = match eval(*left) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
let right = match eval(*right) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
Ok(match op {
|
||||
let left = eval(*left);
|
||||
let right = eval(*right);
|
||||
match op {
|
||||
Operation::Add => left + right,
|
||||
Operation::Sub => left - right,
|
||||
Operation::Mul => left * right,
|
||||
Operation::Div => {
|
||||
if right == 0 {
|
||||
return Err(String::from("division by zero"));
|
||||
} else {
|
||||
left / right
|
||||
}
|
||||
}
|
||||
})
|
||||
Operation::Div => left / right,
|
||||
}
|
||||
}
|
||||
Expression::Value(v) => Ok(v),
|
||||
Expression::Value(v) => v,
|
||||
}
|
||||
}
|
||||
|
||||
// ANCHOR: tests
|
||||
#[test]
|
||||
fn test_value() {
|
||||
assert_eq!(eval(Expression::Value(19)), Ok(19));
|
||||
assert_eq!(eval(Expression::Value(19)), 19);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -81,7 +69,7 @@ fn test_sum() {
|
||||
left: Box::new(Expression::Value(10)),
|
||||
right: Box::new(Expression::Value(20)),
|
||||
}),
|
||||
Ok(30)
|
||||
30
|
||||
);
|
||||
}
|
||||
|
||||
@ -107,7 +95,7 @@ fn test_recursion() {
|
||||
left: Box::new(term1),
|
||||
right: Box::new(term2),
|
||||
}),
|
||||
Ok(85)
|
||||
85
|
||||
);
|
||||
}
|
||||
|
||||
@ -119,7 +107,7 @@ fn test_zeros() {
|
||||
left: Box::new(Expression::Value(0)),
|
||||
right: Box::new(Expression::Value(0))
|
||||
}),
|
||||
Ok(0)
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
eval(Expression::Op {
|
||||
@ -127,7 +115,7 @@ fn test_zeros() {
|
||||
left: Box::new(Expression::Value(0)),
|
||||
right: Box::new(Expression::Value(0))
|
||||
}),
|
||||
Ok(0)
|
||||
0
|
||||
);
|
||||
assert_eq!(
|
||||
eval(Expression::Op {
|
||||
@ -135,19 +123,7 @@ fn test_zeros() {
|
||||
left: Box::new(Expression::Value(0)),
|
||||
right: Box::new(Expression::Value(0))
|
||||
}),
|
||||
Ok(0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_error() {
|
||||
assert_eq!(
|
||||
eval(Expression::Op {
|
||||
op: Operation::Div,
|
||||
left: Box::new(Expression::Value(99)),
|
||||
right: Box::new(Expression::Value(0)),
|
||||
}),
|
||||
Err(String::from("division by zero"))
|
||||
0
|
||||
);
|
||||
}
|
||||
// ANCHOR_END: tests
|
||||
|
Loading…
x
Reference in New Issue
Block a user