从 Option 中提取 Result - Rust By Example
Description: Rust by Example (RBE) is a collection of runnable examples that illustrate various Rust concepts and standard libraries.

## Keyboard shortcuts

Press `←` or `→` to navigate between chapters

Press `S` or `/` to search in the book

Press `?` to show this help

Press `Esc` to hide this help

# 从 `Option` 中提取 `Result`

处理混合错误类型最基本的方法是将它们相互嵌套。

    use std::num::ParseIntError;

    fn double_first(vec: Vec<&str>) -> Option<Result<i32, ParseIntError>> {
        vec.first().map(|first| {
            first.parse::<i32>().map(|n| 2 * n)
        })
    }

    fn main() {
        let numbers = vec!["42", "93", "18"];
        let empty = vec![];
        let strings = vec!["tofu", "93", "18"];

        println!("第一个数的两倍是 {:?}", double_first(numbers));

        println!("第一个数的两倍是 {:?}", double_first(empty));
        // 错误 1：输入向量为空

        println!("第一个数的两倍是 {:?}", double_first(strings));
        // 错误 2：元素无法解析为数字
    }

有时我们希望在遇到错误时停止处理（例如使用 `?`），但在 `Option` 为 `None` 时继续执行。这时 `transpose` 函数就派上用场了，它可以方便地交换 `Result` 和 `Option`。

    use std::num::ParseIntError;

    fn double_first(vec: Vec<&str>) -> Result<Option<i32>, ParseIntError> {
        let opt = vec.first().map(|first| {
            first.parse::<i32>().map(|n| 2 * n)
        });

        opt.transpose()
    }

    fn main() {
        let numbers = vec!["42", "93", "18"];
        let empty = vec![];
        let strings = vec!["tofu", "93", "18"];

        println!("第一个数的两倍是 {:?}", double_first(numbers));
        println!("第一个数的两倍是 {:?}", double_first(empty));
        println!("第一个数的两倍是 {:?}", double_first(strings));
    }