rust有两类异常处理方式,panic和类型系统。
1. Panic
panic类比于C++和Java的Throw机制,通过panic,可以直接抛出异常,避免层层传递异常。
使用panic宏抛出异常
panic!("error")
捕获异常
use std::panic;
let result = panic::catch_unwind(|| {
println!("hello!");
});
assert!(result.is_ok());
let result = panic::catch_unwind(|| {
panic!("oh no!");
});
assert!(result.is_err());
rust用catch_unwind捕获异常,传入参数是闭包。当捕获到异常,其结果是Result。
2. 类型系统
Result的定义是枚举,定义如下
enum Result<T, E> {
Ok(T),
Err(E),
}
其中OK表示正常返回结果,Err表示返回错误。错误处理匹配方法
match get_weather(hometown) {
Ok(report) => {
display_weather(hometown, &report);
}
Err(err) => {
println!("error querying the weather: {}", err);
schedule_weather_retry();
}
}
2.1 ?操作符
?操作符等价于
match result {
Ok(v) => v,
Err(e) => return Err(e.into())
}
当结果是Err时,就直接返回Err,使用这个语法糖,可以简要处理
use std::fs::File;
use std::io::Read;
fn read_file(name: &str) -> Result<String, std::io::Error> {
let mut f = File::open(name)?;
let mut contents = String::new();
f.read_to_string(&mut contents)?;
Ok(contents)
}
如果open或者read的时候,有Err就直接return,如果没有就最后返回Ok。
2.2 Result.unwrap()
'''
let num = digits.parse::<u64>().unwrap();
'''
当表达不可能发生的错误,使用unwrap, 如果返回的Result是OK,则返回OK包含的值,如果返回Err,则用Panic抛出Err。
小结
rust综合了C++语言面向对象的异常抛出机制和Haskell和Erlang函数式语言的类型系统错误机制,并且通过?unwrap()等语法糖,简洁的表达异常抛出和传递机制。