?

使用匹配链接结果会得到极其繁琐的内容;幸运的是,? 运算符可以使事情再次变得干净漂亮。? 运算符用在返回值为 Result 的表式式后面,等同于这样一个匹配表式,其中 Err(err) 分支展开成提前(返回)return Err(err),同时 Ok(ok) 分支展开成 ok 表达式。

  1. mod checked {
  2. #[derive(Debug)]
  3. enum MathError {
  4. DivisionByZero,
  5. NegativeLogarithm,
  6. NegativeSquareRoot,
  7. }
  8. type MathResult = Result<f64, MathError>;
  9. fn div(x: f64, y: f64) -> MathResult {
  10. if y == 0.0 {
  11. Err(MathError::DivisionByZero)
  12. } else {
  13. Ok(x / y)
  14. }
  15. }
  16. fn sqrt(x: f64) -> MathResult {
  17. if x < 0.0 {
  18. Err(MathError::NegativeSquareRoot)
  19. } else {
  20. Ok(x.sqrt())
  21. }
  22. }
  23. fn ln(x: f64) -> MathResult {
  24. if x < 0.0 {
  25. Err(MathError::NegativeLogarithm)
  26. } else {
  27. Ok(x.ln())
  28. }
  29. }
  30. // 中间函数
  31. fn op_(x: f64, y: f64) -> MathResult {
  32. // 如果 `div` “失败”了,那么 `DivisionByZero` 将被返回
  33. let ratio = div(x, y)?;
  34. // 如果 `ln` “失败”了,那么 `NegativeLogarithm` 将被返回
  35. let ln = ln(ratio)?;
  36. sqrt(ln)
  37. }
  38. pub fn op(x: f64, y: f64) {
  39. match op_(x, y) {
  40. Err(why) => panic!(match why {
  41. MathError::NegativeLogarithm
  42. => "logarithm of negative number",
  43. MathError::DivisionByZero
  44. => "division by zero",
  45. MathError::NegativeSquareRoot
  46. => "square root of negative number",
  47. }),
  48. Ok(value) => println!("{}", value),
  49. }
  50. }
  51. }
  52. fn main() {
  53. checked::op(1.0, 10.0);
  54. }

记得查阅文档,里面有很多匹配/组合 Result