将结果转换为选项的简洁方法是什么?

What is a clean way to convert a Result into an Option?

在更新到较新的 Rust 版本之前,以下曾经起作用:

fn example(val: &[&str]) {
    let parsed_value: Vec<usize> = val
        .iter()
        .filter_map(|e| e.parse::<usize>())
        .collect();
}

但是,现在解析方法 returns 是 Result 类型而不是 Option,我得到错误:

error[E0308]: mismatched types
 --> src/lib.rs:4:25
  |
4 |         .filter_map(|e| e.parse::<usize>())
  |                         ^^^^^^^^^^^^^^^^^^ expected enum `std::option::Option`, found enum `std::result::Result`
  |
  = note: expected type `std::option::Option<_>`
             found type `std::result::Result<usize, std::num::ParseIntError>`

我可以通过条件创建一个 Option,但是有更好/更简洁的方法吗?

使用Result::ok。为清楚起见添加的类型:

let res: Result<u8, ()> = Ok(42);
let opt: Option<u8> = res.ok();
println!("{:?}", opt);

为了对称起见,还有 Option::ok_or and Option::ok_or_elseOptionResult


在你的例子中,你有一个迭代器。

如果您想忽略 失败,请使用Iterator::flat_map。由于 Result(和 Option)实施 IntoIterator,这有效:

let parsed_value: Vec<usize> = val
    .iter()
    .flat_map(|e| e.parse())
    .collect();

如果你想在第一次失败时停止,你可以collect进入一个大Result。这不太明显,但您可以查看 FromIterator 的实现者以获取 collect-able 项目的完整列表。

let parsed_value: Result<Vec<usize>, _> = val
    .iter()
    .map(|e| e.parse())
    .collect();

当然,您可以将大 Result 转换为 Option,如第一个示例所示。