Rust错误处理

Rust错误处理

简介

Rust将错误分为两个主要类别:

  • 可恢复错误(recoverable) : 由 Result<T, E> 表示,代表向用户报告错误和重试操作是合理的情况,比如未找到文件。

  • 不可恢复错误(unrecoverable): 由panic!处理,是bug的同义词,比如尝试访问超过数组结尾的位置。

Rust没有异常。

Option

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<T, E>

ResultOption的更通用的版本,它解释了结果错误的原因.

1
2
3
4
enum Result<T, E> {
    Ok(T),
    Err(E),
}

Result 枚举和其成员也被导入到了 prelude 中,所以就不需要 OkErr 之前指定 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! 宏可用于产生一个panic(恐慌),并开始回退(unwind)它的栈;

?运算符

? 运算符用在返回值为 Result 的表达式后面,它等同于这样一个匹配 表达式:

  • Err(err) 分支展开成提前返回的 return Err(err);

  • Ok(ok) 分支展开成 ok 表达式;

  • ? 之后直接使用链式方法调用来进一步缩短代码:

 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)
}

参考

updatedupdated2024-05-102024-05-10