本章导读
回想一下,你是否曾在周五下午部署上线后,被一个隐藏极深的
NullPointerException或KeyError炸得人仰马翻?在 Java 和 Python 中,异常(Exception)像是一个隐形的传送门。当错误发生时,程序流程会突然跳跃,你必须小心翼翼地在调用栈的上层布下
try-catch的天罗地网。这种机制虽然方便,但也导致了“Happy Path”(快乐路径)编程习惯——我们总是假设一切顺利,把错误处理当作事后的补丁。Rust 没有 Exception。没错,没有
throw,没有catch。Rust 强迫你直面每一个可能出错的环节。这听起来像是一种折磨,但相信我,一旦你习惯了 Rust 的
Result和Option,你会发现那是一种前所未有的安全感。你的代码将变得像坦克一样坚固,绝不会因为一个未捕获的异常而全线崩溃。这一章,我们将学会如何优雅地对付“墨菲定律”。
🎯 本章学习目标
- 消灭 Null:理解
Option<T>如何在编译期根除空指针异常。 - 理解 Result:掌握
Result<T, E>类型,学会把错误当作普通数据来处理。 - 优雅传播:学会使用
?操作符,写出比 Python 更简洁的错误传播代码。 - 工程化实战:构建一个健壮的配置文件解析器,处理 I/O 错误和解析错误。
- AI 辅助:利用 AI 快速生成自定义错误类型模板。
4.1 告别十亿美元的错误:Option
Tony Hoare(Null 的发明者)曾称 Null 引用是他“十亿美元的错误”。在 Java 中,任何对象都可能是 null;在 Python 中,变量可能是 None。
Rust 在语言层面移除了 Null。如果一个值可能不存在,你必须把它包裹在 Option 枚举中。
4.1.1 强制开箱
// 定义:Option 只有两个值:Some(数据) 或 None
enum Option<T> {
Some(T),
None,
}
实战对比:查找用户
-
Java 写法:
User user = findUser("Alice"); if (user != null) { // 忘了这行?生产环境见! System.out.println(user.getName()); } -
Rust 写法:
fn find_user(name: &str) -> Option<String> { if name == "Alice" { Some("Alice Cooper".to_string()) } else { None } } fn main() { let user_option = find_user("Bob"); // 编译错误!你不能直接把 Option<String> 当 String 用 // println!("User: {}", user_option); // 正确做法:必须处理 None 的情况 match user_option { Some(name) => println!("找到用户: {}", name), None => println!("查无此人"), } }
💡 小贴士 (Pro Tip)
觉得
match太啰嗦?如果你只关心有值的情况,可以用if let语法糖:
if let Some(name) = user_option { println!("{}", name); }
这读起来就像 Python 英语一样自然。
4.2 Result<T, E>:错误也是一种数据
在 Rust 中,错误分为两类:
- 不可恢复错误:
panic!。比如数组越界。程序会直接挂掉(类似System.exit但会打印堆栈)。 - 可恢复错误:
Result<T, E>。比如文件不存在、网络超时。这是本章的重点。
enum Result

309

被折叠的 条评论
为什么被折叠?



