我试图了解如何在Rust中使用问号运算符进行错误处理。我有以下代码:
fn main() -> Result<(), &'static str> {
let foo: i32 = Some("1")
.ok_or(Err("error 1"))?
.parse()
.or(Err("error 2"))?;
Ok(())
}
由于某些原因,无法编译此代码:
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有一个问号运算符的用法示例:
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)
}
我认为,在处理错误的意义上,它与我的示例没有太大区别。我看不到代码无效的原因。如果应该为所有From
实现Result
特性,为什么Rust书中的代码可以正常工作?
答案 0 :(得分: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(())
}
错误消息提及From
特征的原因是因为?
隐式使用From
将表达式的错误类型转换为返回值的错误类型。如果有效,.ok_or(Err("error 1"))
将返回值Result<&'static str, Result<_, &'static str>>
(_
几乎可以是任何东西,因为Err
未指定)。 ?
运算符试图找到将From
(表达式的错误类型)转换为Result<_, &'static str>
(返回值的错误类型)的&'static str
实现。由于不存在这样的From
实现,因此编译器会发出错误。