如何将一个 Option<Result<T, Error>> 转换为 Option<T>,而不需要解包它?

4

我试图寻找一种好的方法,将Option<String>转换为Option<i8>

例如:

use std::str::FromStr;

fn main() {
    let some_option: Option<String> = Some("too".to_owned()); 
    let new_option: Option<i8> = some_option.map(|x| i8::from_str(x.as_str())); 
}

我原以为我可以使用turbo fish来显式转换类型,就像这样:

use std::str::FromStr;

fn main() {
    let some_option: Option<String> = Some("too".to_owned()); 
    let new_option: Option<i8> = some_option.map::<Option<i8>>(|x| i8::from_str(x.as_str())); 
}

然而,编译器指出这不是正确的参数数量,所以我认为这可能有效,但它并没有。
use std::str::FromStr;

fn main() {
    let some_option: Option<String> = Some("too".to_owned()); 
    let new_option: Option<i8> = some_option.map::<Option<i8>,i8::from_str>(); 
}
2个回答

8
您可以使用ok()unwrap_or()函数:
fn test() -> Option<Result<u32, ()>> {
    Some(Ok(1))
}

fn main() {
    let x: Option<Result<_, _>> = test();
    println!("{:?}", x.map(|r| r.ok()).unwrap_or(None));
}

7

不必首先创建一个Option<Result<T, E>>,而可以结合以下方法:

  1. Option::and_then,应用返回Option的闭包并压平结果。

  2. Result::ok,将Result转换为Option,丢弃错误。

fn main() {
    let some_option = Some("too".to_owned()); 
    let new_option = some_option.and_then(|x| x.parse::<u8>().ok()); 
}

您可以使用相同的两个工具来回答您的直接问题:
fn convert<T, E>(a: Option<Result<T, E>>) -> Option<T> {
    a.and_then(Result::ok)
}

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