解答

1. /// An operation to perform on two subexpressions.
2. #[derive(Debug)]
3. enum Operation {
4. Add,
5. Sub,
6. Mul,
7. Div,
8. }

10. /// An expression, in tree form.
11. #[derive(Debug)]
12. enum Expression {
13. /// An operation on two subexpressions.
14. Op { op: Operation, left: Box<Expression>, right: Box<Expression> },

16. /// A literal value
17. Value(i64),
18. }

20. fn eval(e: Expression) -> Result<i64, String> {
21. match e {
22. Expression::Op { op, left, right } => {
23. let left = match eval(*left) {
24. Ok(v) => v,
25. e @ Err(_) => return e,
26. };
27. let right = match eval(*right) {
28. Ok(v) => v,
29. e @ Err(_) => return e,
30. };
31. Ok(match op {
32. Operation::Add => left + right,
33. Operation::Sub => left - right,
34. Operation::Mul => left * right,
35. Operation::Div => {
36. if right == 0 {
37. return Err(String::from("division by zero"));
38. } else {
39. left / right
40. }
41. }
42. })
43. }
44. Expression::Value(v) => Ok(v),
45. }
46. }

48. #[test]
49. fn test_value() {
50. assert_eq!(eval(Expression::Value(19)), Ok(19));
51. }

53. #[test]
54. fn test_sum() {
55. assert_eq!(
56. eval(Expression::Op {
57. op: Operation::Add,
58. left: Box::new(Expression::Value(10)),
59. right: Box::new(Expression::Value(20)),
60. }),
61. Ok(30)
62. );
63. }

65. #[test]
66. fn test_recursion() {
67. let term1 = Expression::Op {
68. op: Operation::Mul,
69. left: Box::new(Expression::Value(10)),
70. right: Box::new(Expression::Value(9)),
71. };
72. let term2 = Expression::Op {
73. op: Operation::Mul,
74. left: Box::new(Expression::Op {
75. op: Operation::Sub,
76. left: Box::new(Expression::Value(3)),
77. right: Box::new(Expression::Value(4)),
78. }),
79. right: Box::new(Expression::Value(5)),
80. };
81. assert_eq!(
82. eval(Expression::Op {
83. op: Operation::Add,
84. left: Box::new(term1),
85. right: Box::new(term2),
86. }),
87. Ok(85)
88. );
89. }

91. #[test]
92. fn test_error() {
93. assert_eq!(
94. eval(Expression::Op {
95. op: Operation::Div,
96. left: Box::new(Expression::Value(99)),
97. right: Box::new(Expression::Value(0)),
98. }),
99. Err(String::from("division by zero"))
100. );
101. }

103. fn main() {
104. let expr = Expression::Op {
105. op: Operation::Sub,
106. left: Box::new(Expression::Value(20)),
107. right: Box::new(Expression::Value(10)),
108. };
109. println!("expr: {:?}", expr);
110. println!("result: {:?}", eval(expr));
111. }