解答

  1. /// An operation to perform on two subexpressions.
  2. #[derive(Debug)]
  3. enum Operation {
  4. Add,
  5. Sub,
  6. Mul,
  7. Div,
  8. }
  9. /// An expression, in tree form.
  10. #[derive(Debug)]
  11. enum Expression {
  12. /// An operation on two subexpressions.
  13. Op { op: Operation, left: Box<Expression>, right: Box<Expression> },
  14. /// A literal value
  15. Value(i64),
  16. }
  17. fn eval(e: Expression) -> Result<i64, String> {
  18. match e {
  19. Expression::Op { op, left, right } => {
  20. let left = match eval(*left) {
  21. Ok(v) => v,
  22. e @ Err(_) => return e,
  23. };
  24. let right = match eval(*right) {
  25. Ok(v) => v,
  26. e @ Err(_) => return e,
  27. };
  28. Ok(match op {
  29. Operation::Add => left + right,
  30. Operation::Sub => left - right,
  31. Operation::Mul => left * right,
  32. Operation::Div => {
  33. if right == 0 {
  34. return Err(String::from("division by zero"));
  35. } else {
  36. left / right
  37. }
  38. }
  39. })
  40. }
  41. Expression::Value(v) => Ok(v),
  42. }
  43. }
  44. #[test]
  45. fn test_value() {
  46. assert_eq!(eval(Expression::Value(19)), Ok(19));
  47. }
  48. #[test]
  49. fn test_sum() {
  50. assert_eq!(
  51. eval(Expression::Op {
  52. op: Operation::Add,
  53. left: Box::new(Expression::Value(10)),
  54. right: Box::new(Expression::Value(20)),
  55. }),
  56. Ok(30)
  57. );
  58. }
  59. #[test]
  60. fn test_recursion() {
  61. let term1 = Expression::Op {
  62. op: Operation::Mul,
  63. left: Box::new(Expression::Value(10)),
  64. right: Box::new(Expression::Value(9)),
  65. };
  66. let term2 = Expression::Op {
  67. op: Operation::Mul,
  68. left: Box::new(Expression::Op {
  69. op: Operation::Sub,
  70. left: Box::new(Expression::Value(3)),
  71. right: Box::new(Expression::Value(4)),
  72. }),
  73. right: Box::new(Expression::Value(5)),
  74. };
  75. assert_eq!(
  76. eval(Expression::Op {
  77. op: Operation::Add,
  78. left: Box::new(term1),
  79. right: Box::new(term2),
  80. }),
  81. Ok(85)
  82. );
  83. }
  84. #[test]
  85. fn test_error() {
  86. assert_eq!(
  87. eval(Expression::Op {
  88. op: Operation::Div,
  89. left: Box::new(Expression::Value(99)),
  90. right: Box::new(Expression::Value(0)),
  91. }),
  92. Err(String::from("division by zero"))
  93. );
  94. }
  95. fn main() {
  96. let expr = Expression::Op {
  97. op: Operation::Sub,
  98. left: Box::new(Expression::Value(20)),
  99. right: Box::new(Expression::Value(10)),
  100. };
  101. println!("expr: {:?}", expr);
  102. println!("result: {:?}", eval(expr));
  103. }