外观
第 2 节:Result 方法宝库
Result 是"带原因的 Option"——Option 的那套方法(map/unwrap_or/is_some……),Result 全有对应版,还多了几个自己的王牌。
map / map_err:加工值 / 翻译错误 ⭐
rust
let raw = std::fs::read_to_string("不存在.txt");
let friendly = raw.map_err(|e| format!("读取文件失败:{}", e));
// Err("读取文件失败:系统找不到指定的文件 (os error 2)")map(闭包):成功就加工值(第 1 节 Option 同款)map_err(闭包):失败就翻译错误——把底层错误变成用户能懂的话,第 8 章map_err的老朋友,真实项目每天用
and_then / or_else:成功接力 / 失败接力 ⭐
rust
fn parse(text: &str) -> Result<u32, String> {
text.parse().map_err(|_| "不是数字".to_string())
}
// and_then:成功才继续,失败直接短路
let double = parse("42").and_then(|n| Ok(n * 2));
// Ok(84)
// or_else:失败才接力(兜底/重试)
let fallback = parse("abc").or_else(|e| {
println!("第一次失败:{}", e);
parse("10")
});
// Ok(10)and_then:前面成功,后面才有资格跑——"先解析,再查数据库"or_else:前面失败,才轮到备胎——"主路径失败,走兜底"、"重试一次"
is_ok / is_err:只问成败 ⭐
rust
if result.is_ok() { /* 成功了 */ }
if result.is_err() { /* 失败了 */ }配合第 18 章的 matches! 还能写条件:
rust
if matches!(result, Err(_)) { /* 失败才进来 */ }unwrap_or_else:失败给默认值 ✨
rust
let port: u32 = parse("8080").unwrap_or_else(|_| 0);
// 失败就用 0(或"加载默认配置")和 unwrap_or 的区别:备胎是"现算的"(闭包),适合备胎昂贵或要依赖错误信息时。
inspect / inspect_err:偷看一眼,不改变结果 ✨
rust
let result = parse("42")
.inspect(|n| println!("解析出 {}", n)) // 成功时看一眼
.inspect_err(|e| eprintln!("失败了 {}", e)); // 失败时看一眼
// 结果原样传下去调试神器:想在方法链中间打日志,又不想拆链——inspect 是"看一眼就放行"。
记忆口诀
map 加工值,map_err 翻译错,and_then 成功接力,or_else 失败兜底,is_ok 问一句,inspect 偷看。 和 Option 那套一一对应:想不起来时,先想 Option 版,再加"原因"就是 Result 版。
常见误用
用 ? 的场合写成了 or_else——or_else 是"失败时换一种做法",不是"失败时退出";想退出用 ?(第 8 章)。
map_err 拼错消息——记住三问:什么操作、什么数据、下一步怎么办(错误处理篇雷区 4 的遗言标准,map_err 同样适用)。