Упражнение: Замена на Result
В этом упражнении мы возвращаемся к упражнению с вычислителем выражений, которое делали во второй день. Наше первоначальное решение игнорирует возможный случай ошибки: деление на ноль! Перепишите eval, чтобы использовать идиоматичную обработку ошибок для этого случая и возвращать ошибку, когда она возникает. Мы предоставляем простой тип DivideByZeroError, который будет типом ошибки для eval.
// Copyright 2023 Google LLC
// SPDX-License-Identifier: Apache-2.0
/// Операция, которую нужно выполнить над двумя подвыражениями.
#[derive(Debug)]
enum Operation {
Add,
Sub,
Mul,
Div,
}
/// Выражение в виде дерева.
#[derive(Debug)]
enum Expression {
/// Операция над двумя подвыражениями.
Op { op: Operation, left: Box<Expression>, right: Box<Expression> },
/// Литеральное значение
Value(i64),
}
#[derive(PartialEq, Eq, Debug)]
struct DivideByZeroError;
// Исходная реализация вычислителя выражений. Обновите её, чтобы
// возвращать `Result` и создавать ошибку при делении на 0.
fn eval(e: Expression) -> i64 {
match e {
Expression::Op { op, left, right } => {
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 {
left / right
} else {
panic!("Cannot divide by zero!");
},
}
}
Expression::Value(v) => v,
}
}
#[cfg(test)]
mod test {
use super::*;
#[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(DivideByZeroError)
);
}
#[test]
fn test_ok() {
let expr = Expression::Op {
op: Operation::Sub,
left: Box::new(Expression::Value(20)),
right: Box::new(Expression::Value(10)),
};
assert_eq!(eval(expr), Ok(10));
}
}
This slide and its sub-slides should take about 20 minutes.
- Стартовый код здесь не совсем такой же, как решение предыдущего упражнения: мы добавили явную панику, чтобы показать студентам, где находится случай ошибки. Укажите на это, если студенты запутаются.