我希望在条件为真的情况下从函数返回错误:
use std::error::Error;
pub fn run() -> Result<(), Box<Error>> {
// -- snip ---
if condition {
// return error
}
// -- snip --
Ok(())
}
fn main() {}
我可能没有类型系统的基础知识,但我看到的每个人都使用?
运算符,所以我无法弄清楚要返回的类型。
Error
是一个特征,你想要返回一个特征对象(注意dyn
keyword),所以你需要实现这个特性:
use std::error::Error;
use std::fmt;
#[derive(Debug)]
struct MyError(String);
impl fmt::Display for MyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "There is an error: {}", self.0)
}
}
impl Error for MyError {}
pub fn run() -> Result<(), Box<dyn Error>> {
let condition = true;
if condition {
return Result::Err(Box::new(MyError("Oops".into())));
}
Ok(())
}
fn main() {
if let Err(e) = run() {
println!("{}", e); // "There is an error: Oops"
}
}
Debug
,Display
,然后Error
,Err
的Result
变体。我建议你使用failure删除所有错误样板:
#[derive(Fail, Debug)]
#[fail(display = "There is an error: {}.", _0)]
struct MyError(String);
--
请注意,如果你期望一个Error
,你可以返回你想要的任何类型,因为它实现了Error
。这包括std
中的错误类型。
Result<T, E>
是一个有两个变体的枚举。要返回其中任何一个,只需使用相应的变体即可。
fn foo(var: bool) -> Result<(), i32> {
if var {
Ok(()) //in fact this is std::result::Result::Ok
} else {
Err(-3) //in fact this is std::result::Result::Err
}
}
你不必写std::result::Result::Ok
的原因是它在prelude。如您所见,您不必坚持使用Box<Error>
,但可以返回您想要的任何类型。它是一个通用的枚举,没有任何限制。
?
-operator是一个handy shortcut for early returns,因此你不必对结果过于冗长。
我是Rust的新手,但是这是我的脏黑客返回自定义错误,因为该函数设置为返回Result<(), Box<dyn Error>>
:
fn serve(config: &Config, stream: TcpStream) -> Result<(), Box<dyn Error>> {
// ...
if request_is_bad() {
// This returns immediately a custom "Bad request" error
Err("Bad request")?;
}
// ...
}