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

ast*_*ver 3 rust

我试图找到一个很好的方法来转换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())); 
}
Run Code Online (Sandbox Code Playgroud)

我以为我可以使用涡轮鱼来明确地转换类型,如下所示:

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())); 
}
Run Code Online (Sandbox Code Playgroud)

但是,编译器指出这不是正确的参数量,所以我认为这可能有效,但它不会:

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>(); 
}
Run Code Online (Sandbox Code Playgroud)

Wes*_*ser 7

你可以使用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));
}
Run Code Online (Sandbox Code Playgroud)


She*_*ter 7

Option<Result<T, E>>您可以组合:而不是首先创建一个:

  1. Option::and_then,它应用一个返回Option和平展结果的闭包.

  2. Result::ok,它转换一个ResultOption,丢弃错误.

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

您可以使用相同的两个工具来回答您的直接问题:

fn convert<T, E>(a: Option<Result<T, E>>) -> Option<T> {
    a.and_then(Result::ok)
}
Run Code Online (Sandbox Code Playgroud)