Rust将错误分为两个主要类别:
可恢复错误(recoverable) : 由 Result<T, E>
表示,代表向用户报告错误和重试操作是合理的情况,比如未找到文件。
不可恢复错误(unrecoverable): 由panic!
处理,是bug的同义词,比如尝试访问超过数组结尾的位置。
Rust没有异常。
Option<T>
是Rust的系统类型,用来表示值不存在的可能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| // option
enum Option<T> {
None, //选项为空
Some(T), //选项不为空,存在一个T
}
//
impl<T> Option<T> {
// unwrap: 当遇到None值时会panic
fn unwrap(self) -> T {
match self {
Option::Some(val) => val,
Option::None => panic!("unwrap option None"),
}
}
}
//
fn unwrap_or<T>(option: Option<T>, default: T) -> T {
match option {
None => default,
Some(value) => value,
}
}
//
fn and_then<F, T, A>(option: Option<T>, f: F) -> Option<A>
where F: FnOnce(T) -> Option<A> {
match option {
None => None,
Some(value) => f(value),
}
}
fn ok_or<T, E>(option: Option<T>, err: E) -> Result<T, E> {
match option {
Some(val) => Ok(val),
None => Err(err),
}
}
|
Result
是Option
的更通用的版本,它解释了结果错误的原因.
1
2
3
4
| enum Result<T, E> {
Ok(T),
Err(E),
}
|
Result
枚举和其成员也被导入到了 prelude 中,所以就不需要 Ok
和 Err
之前指定 Result::
。
1
2
3
4
| //unwrap: 如果 Result 值是 Ok,返回 Ok 中的值,如果是 Err会自动调用 panic!。
let f = File::open("hello.txt").unwrap();
//expect: 可以在参数中自定义要显示的错误信息,并在自动调用 panic! 时,显示在错误信息中,有助于追踪 panic 的根源。
let f = File::open("hello.txt").expect("Failed to open hello.txt");
|
panic!
宏可用于产生一个panic(恐慌),并开始回退(unwind)它的栈;
?
运算符用在返回值为 Result
的表达式后面,它等同于这样一个匹配 表达式:
1
2
3
4
5
6
7
8
9
10
11
| use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let mut s = String::new();
File::open("hello.txt")?.read_to_string(&mut s)?; //? 只能用于返回值类型为 Result 的函数。
Ok(s)
}
|