7.2 使用 Result 进行可恢复错误处理
听
Rust 将大多数运行时错误视为可恢复的,即程序在出错后仍有机会继续执行或优雅降级。为此,标准库提供了 Result<T, E> 枚举类型,作为表达操作成功或失败的标准方式。
Result 的定义与基本用法
Result 定义如下:
enum Result<T, E> {
Ok(T),
Err(E),
}
Ok(T)包含成功时的结果值;Err(E)包含错误信息,通常是一个实现了std::error::Errortrait 的类型。
例如,尝试打开一个文件:
use std::fs::File;
let f = File::open("hello.txt");
File::open 返回 Result<File, std::io::Error>。如果文件存在且可读,返回 Ok(file);否则返回 Err(error)。
使用 match 处理 Result
最直接的方式是使用 match 对 Result 进行模式匹配:
match f {
Ok(file) => {
println!("File opened successfully");
// 使用 file
}
Err(error) => {
println!("Failed to open file: {}", error);
}
}
这种写法显式、安全,并强制处理两种可能结果。
组合器方法简化处理
除了 match,Result 提供了多种组合器方法,适用于链式操作:
unwrap():若为Ok,返回内部值;若为Err,则 panic(仅用于原型或确定不会失败的场景)。expect(msg):类似unwrap,但可自定义 panic 信息。unwrap_or(default):失败时返回默认值。map(f):若成功,对值应用函数f;否则保持Err。and_then(f):若成功,调用f(返回另一个Result),实现链式错误传播。
示例:
let content = File::open("data.txt")
.and_then(|f| std::io::read_to_string(f))
.unwrap_or_else(|e| {
eprintln!("Error reading file: {}", e);
String::new()
});
错误类型的选择
标准库中常见的错误类型包括:
std::io::Error:I/O 操作错误;std::num::ParseIntError:整数解析失败;std::string::FromUtf8Error:UTF-8 解码错误。
这些类型都实现了 std::error::Error trait,支持统一处理和格式化输出。
为什么 Result 更安全
与异常或返回错误码不同,Result 将错误编码在类型系统中:
- 编译器强制你处理或显式忽略错误;
- 不会因忘记检查而跳过错误;
- 错误值携带上下文信息,便于诊断。
小结
Result<T, E> 是 Rust 处理可恢复错误的核心机制。通过模式匹配或组合器方法,开发者可以清晰、安全地表达“成功路径”和“失败路径”。它鼓励显式错误处理,避免隐藏的失败逻辑,是构建可靠系统的基础。在后续章节中,我们将学习如何通过 ? 操作符进一步简化错误传播,以及如何定义自己的错误类型以提升代码的可维护性。
#Rust 入门教程
分享于 1 周前
上一篇:7.1 panic! 与不可恢复错误
下一篇:7.3 ? 操作符简化错误传播