如何正确使用Option :: ok_or()方法?

st_*_*st_ 2 error-handling rust

我试图了解如何在Rust中使用问号运算符进行错误处理.我有这个代码:

fn main() -> Result<(), &'static str> {
    let foo: i32 = Some("1")
        .ok_or(Err("error 1"))?
        .parse()
        .or(Err("error 2"))?;
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

由于某些原因,无法编译此代码:

error[E0277]: the trait bound `&str: std::convert::From<std::result::Result<_, &str>>` is not satisfied
 --> src/main.rs:2:20
  |
2 |       let foo: i32 = Some("1")
  |  ____________________^
3 | |         .ok_or(Err("error 1"))?
  | |_______________________________^ the trait `std::convert::From<std::result::Result<_, &str>>` is not implemented for `&str`
  |
  = note: required by `std::convert::From::from`
Run Code Online (Sandbox Code Playgroud)

Rust书中有问号运算符的示例用法:

use std::io;
use std::io::Read;
use std::fs::File;

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();

    File::open("hello.txt")?.read_to_string(&mut s)?;

    Ok(s)
}
Run Code Online (Sandbox Code Playgroud)

在我看来,它在处理错误方面与我的例子没有太大差别.我看不出我的代码无效的原因.如果From应该为所有类型实现特性,Result为什么Rust书中的代码工作正常?

tre*_*tcl 6

不同or,ok_or取一个E,而不是一个完整的Result<T, E>(因为如果通过它就没有任何事情要做Ok).只需直接传递错误字符串:

fn main() -> Result<(), &'static str> {
   let foo: i32 = Some("1")
       .ok_or("error 1")?
       .parse()
       .or(Err("error 2"))?;
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

错误消息提到From特征的原因是?隐式使用From将表达式的错误类型转换为返回值的错误类型.如果它工作,.ok_or(Err("error 1"))将返回一个值Result<&'static str, Result<_, &'static str>>(_几乎可以是任何东西,因为Err没有指定).该?操作员试图找到的实现From,将转换Result<_, &'static str>(表达式的错误类型)到&'static str(返回值的错误类型).由于不From存在此类实现,因此编译器会发出错误.