将Result转换为Option的简洁方法是什么?

102

在更新到更近的Rust版本之前,以下代码可以正常运行:

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

然而,现在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>`

我可以通过条件语句创建一个 Option,但是是否有更好/更清晰的方式?

1个回答

148
使用Result::ok。为了清晰起见添加了类型:
let res: Result<u8, ()> = Ok(42);
let opt: Option<u8> = res.ok();
println!("{:?}", opt);

为了对称起见,还有Option::ok_orOption::ok_or_else用于将Option转换为Result


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

如果您想要忽略失败,请使用Iterator::flat_map。由于Result(和Option)实现了IntoIterator,因此这样可以工作:

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

如果您想在第一个故障点停止,则可以将其收集成一个大的Result。这不太明显,但您可以查看FromIterator的实现者以获取完整的可collect列表。

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

当然,你可以像第一个示例一样,将这个大的 Result 转换为一个 Option


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接