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

vis*_*ise 12 optional rust

在更新到更新的Rust版本之前,以下工作原理:

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

但是,现在parse方法返回一个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>`
Run Code Online (Sandbox Code Playgroud)

我可以创建Option一个有条件的,但有更好/更清洁的方式吗?

She*_*ter 21

使用Result::ok.为清晰起见添加了类型

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

为了对称的缘故,这里还有Option::ok_orOption::ok_or_else从去OptionResult.


在您的情况下,您有一个迭代器.

如果您想忽略失败,请使用Iterator::flat_map.从Result(和Option)实现IntoIterator,这工作:

let parsed_value: Vec<usize> = val
    .iter()
    .flat_map(|e| e.parse())
    .collect();
Run Code Online (Sandbox Code Playgroud)

如果你想在第一次失败时停下来,你可以collect成为一个大的Result.这不太明显,但您可以查看实现项FromIterator的完整列表的collect实现者.

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

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