问题
I'm trying to understand how to use the question mark operator for error handling in Rust. I have this code:
fn main() -> Result<(), &'static str> {
let foo: i32 = Some("1")
.ok_or(Err("error 1"))?
.parse()
.or(Err("error 2"))?;
Ok(())
}
This code can not be compiled for some reason:
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`
The Rust book has an example usage of the question mark operator:
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)
}
In my opinion, it doesn't differ much from my example in sense of handling errors. I cannot see a reason for my code to be invalid. If the From
trait should be implemented for all kinds of Result
why does the code from the Rust book work fine?
回答1:
Unlike or
, ok_or
takes an E
, not a full Result<T, E>
(because it wouldn't have anything to do if passed an Ok
). Just pass the error string directly:
fn main() -> Result<(), &'static str> {
let foo: i32 = Some("1")
.ok_or("error 1")?
.parse()
.or(Err("error 2"))?;
Ok(())
}
The reason the error message mentions the From
trait is because ?
implicitly uses From
to convert the expression's error type into the return value's error type. If it worked, .ok_or(Err("error 1"))
would return a value of Result<&'static str, Result<_, &'static str>>
(_
could be almost anything, since Err
doesn't specify). The ?
operator attempts to find an implementation of From
that would convert Result<_, &'static str>
(the expression's error type) into &'static str
(the return value's error type). Since no such From
implementation exists, the compiler emits an error.
来源:https://stackoverflow.com/questions/54046081/how-do-i-use-the-optionok-or-method-correctly