• 组合算子:map
    • 参见:

    组合算子:map

    match 是处理 Option 的一个有效方法。但是你最终会发现很多用例都相当繁琐,特别是操作只有一个有效输入的情况。在这些情况下,可以使用 组合算子(combinator)以模块化方式来管理控制流。

    Option 有一个内置方法 map(),这个组合算子可用于简单映射Some -> SomeNone -> None 的情况。多个不同的 map() 调用可以更灵活地链式连接在一起。

    在下面例子中,process() 轻松取代了前面的所有函数,且更加紧凑。

    1. #![allow(dead_code)]
    2. #[derive(Debug)] enum Food { Apple, Carrot, Potato }
    3. #[derive(Debug)] struct Peeled(Food);
    4. #[derive(Debug)] struct Chopped(Food);
    5. #[derive(Debug)] struct Cooked(Food);
    6. // 削水果皮。如果没有水果,就返回 `None`。
    7. // 否则返回削好皮的水果。
    8. fn peel(food: Option<Food>) -> Option<Peeled> {
    9. match food {
    10. Some(food) => Some(Peeled(food)),
    11. None => None,
    12. }
    13. }
    14. // 和上面一样,我们要在切水果之前确认水果是否已经削皮。
    15. fn chop(peeled: Option<Peeled>) -> Option<Chopped> {
    16. match peeled {
    17. Some(Peeled(food)) => Some(Chopped(food)),
    18. None => None,
    19. }
    20. }
    21. // 和前面的检查类似,但是使用 `map()` 来替代 `match`。
    22. fn cook(chopped: Option<Chopped>) -> Option<Cooked> {
    23. chopped.map(|Chopped(food)| Cooked(food))
    24. }
    25. // 另外一种实现,我们可以链式调用 `map()` 来简化上述的流程。
    26. fn process(food: Option<Food>) -> Option<Cooked> {
    27. food.map(|f| Peeled(f))
    28. .map(|Peeled(f)| Chopped(f))
    29. .map(|Chopped(f)| Cooked(f))
    30. }
    31. // 在尝试吃水果之前确认水果是否存在是非常重要的!
    32. fn eat(food: Option<Cooked>) {
    33. match food {
    34. Some(food) => println!("Mmm. I love {:?}", food),
    35. None => println!("Oh no! It wasn't edible."),
    36. }
    37. }
    38. fn main() {
    39. let apple = Some(Food::Apple);
    40. let carrot = Some(Food::Carrot);
    41. let potato = None;
    42. let cooked_apple = cook(chop(peel(apple)));
    43. let cooked_carrot = cook(chop(peel(carrot)));
    44. // 现在让我们试试更简便的方式 `process()`。
    45. // (原文:Let's try the simpler looking `process()` now.)
    46. // (翻译疑问:looking 是什么意思呢?望指教。)
    47. let cooked_potato = process(potato);
    48. eat(cooked_apple);
    49. eat(cooked_carrot);
    50. eat(cooked_potato);
    51. }

    参见:

    闭包, Option, 和 Option::map()