• ?

    ?

    使用匹配链接结果会得到极其繁琐的内容;幸运的是,? 运算符可以使事情再次变得干净漂亮。? 运算符用在返回值为 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