错误处理
错误处理贯穿软件开发的始终, Rust 提供了许多功能帮助在出现错误时进行对应处理.
Rust 将错误分为两大类:
- 可恢复的(recoverable): 比如"文件不存在"这种错误, 我们一般的处理就是能够将错误上报.
- 不可恢复的(unrecoverable): 不可恢复的错误一般都意味着代码中出现 bug, 比如数组越界访问, 因此直接终止程序是比较合理的选择.
其他语言中可能将这两类错误都统一为 exception(异常). 在 Rust 中没有异常的概念, 而是提供 Result<T,E>
类型对 recoverable 错误进行处理, 另外提供 panic!
宏对 unrecoverable 错误进行处理.
panic!
宏的使用
在代码中有两种方式触发 panic:
- 比如出现数据越界访问时自动触发
- 手动调用
panic!
宏触发 panic
默认情下, panic 时, Rust 程序会打印错误信息, unwind, 清理栈空间, 然后退出.
如果在环境变量中进行设置, 则可以让 Rust 在 panic 时打印当 panic 发生时的调用栈信息, 这样可以非常容易地定位问题所在.
Panic 宏的调用非常简单:
fn main() {
panic!("crash and burn");
}
Rust Panic 时的栈 Unwinding 和忽略
默认情况下, 当 panic 发生时, 程序会自动开始 unwinding
, 即 Rust 会主动推出整个调用栈中的每一帧, 在期间清理每帧中的数据.
但这种退栈和清理一般都有非常大的工作量, 因此 Rust 允许开发者指定不进行 unwinding
, 而是直接 aborting
, 即直接结束程序而不进行清理作业. 这样清理工作就由操作系统接管.
如果想要最终打包的二进制文件尽可能小, 则可以将 panic 处理时的默认 unwinding 行为设置为 aborting 行为.(在 [profile]
中添加 panic = 'abort'
), 比如:
[profile.release]
panic = 'abort'