前言
Rust将错误区分为两类:可恢复;不可恢复。
大部分编程语言并不区分这两类错误,而是采用同一种机制(比如异常)来处理。Rust没有异常,而是用类型Result<T, E>
处理可恢复错误,用宏panic!
处理不可恢复错误,不可恢复错误会终止程序的执行(coredump之类)。
一、宏panic!
示例:
fn main() {
panic!("crash and burn");
}
先打印相关错误日志,然后触发栈解开(stack unwinding),即从最底层栈开始,一直到最高层。同时会清理相关数据。相比直接退出,更优雅。
如果需要panic
达到abort
的效果,正确设置panic = 'abort'
即可。
类似Linux下调用abort
等系统函数终止进程,C++
中的assert
。
二、类型Result
#![allow(unused)]
fn main() {
enum Result<T, E> {
Ok(T),
Err(E),
}
}
enum里头,定义的两个具体值,Ok,Err
,竟然可以是不同类型!!C++
转来的不大习惯,因为enum实质都是整形。
应用
use std::fs::File;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => panic!("Problem opening the file: {:?}", error),
};
}
File::open会返回一个Result<File, Error>类型对象
总结
总体感觉没有多少特殊的。不过强制要求调用方处理异常情况,让程序更鲁棒。因为在C中,函数可以返回空指针,如果调用方不处理,那就直接崩溃(而崩溃不一定是最佳处理)。
有的同学可能刚开始觉得这个限制不好,但其实很多时候,过于自由才会导致更多的问题。比如早期编程,对goto的无节制使用,其实就是一种过于自由,然后最终被证明有害。