rust 教程 05 错误处理
rust中有两种不同的错误处理方式:panic
和Result
panic
这种错误是不应该出现的,这意味着程序本身有bug,例如数组访问越界等。当然也可以像println!
一样显式地调用panic!()
。当这些错误出现时,我们如何处理?rust提供两个方式: unwind stacks(default) 或者 abort process.
unwinding
这种方式使得rust从发生panic的位置开始逐步drop值,从开始位置到调用者到调用者的调用者...。并且panic是每个线程的行为。标准库的std::panic::catch_unwind()
可以捕获这个错误
aborting
有两种情况rust将不会继续unwind stack:
- 如果在drop值时出现了另一个panic
- 使用
-C panic=abort
来进行编译时
Result
rust中的result可以指出可能出现的错误。
捕获错误
result.is_ok()
result.is_err()
返回bool值result.ok()
:返回Option;成功为Some,失败为Noneresult.err()
:类似上一条result.unwrap_or(fallback)
: 返回成功值,失败返回fallbackresult.unwrap_or_else(fallback_fn)
: 对失败值有一个函数处理result.unwrap()
: 返回成功值,否则panicresult.expect()
: 可以增添额外信息result.as_ref()
: 转为引用类型result.as_mut()
打印错误
println!
: 所有错误类型都是可打印的,{}
或者 使用{:?}
获得debug viewerr.to_string()
: 返回错误信息作为Stringerr.source()
: 返回对应的原本错误
注意可以使用anyhow
获得更好的体验
传播错误
?
如果成功,返回正常值;否则立刻return会调用链;注意其也可以应用到option上。
处理多种类型的错误
type GenericError = Box<dyn std::error::Error + Send + Sync + 'static>;
声明自定义的错误类型
使用thiserror
.
use thiserror::Error;
#[derive(Error, Debug)]
#[error("{message:} ({line:})")]
pub struct JsonError {
pub message: String,
pub line: usize,
}