Rust Option 与 Result
Option 表达缺席,Result 表达可恢复失败;二者是标准库枚举,配合组合子与 ? 形成错误处理基础。
#type / concept
#status / growing
#tech / dev
#resource / rust
[!info] 关联笔记
Rust Option 与 Result
这个概念为什么出现
很多语言用 null 或异常表达“没有/失败”。Rust 把它们放进类型系统:
Option<T>:有值或没有Result<T,E>:成功或失败并携带错误
调用方必须处理,或显式传播。
[!abstract] 一句话理解
Option处理缺席;Result处理可恢复失败;通过match/组合子/?强制面对不确定性。
最小可运行示例
场景:用户服务查资料并解析年龄字段
缓存可能没有用户;即使用户存在,年龄字段也可能解析失败。
// 业务意图:按 id 查年龄,区分“没有用户”与“数据坏了”。
// 教学点:Option 与 Result 分层;map/and_then;? 在函数中传播。
fn find_age_text(user_id: u64) -> Option<&'static str> {
match user_id {
1 => Some("29"),
2 => Some("abc"), // 脏数据
_ => None,
}
}
fn parse_age(user_id: u64) -> Result<u8, String> {
let text = find_age_text(user_id).ok_or_else(|| format!("user {user_id} missing"))?;
text.parse::<u8>().map_err(|_| format!("bad age for {user_id}"))
}
fn main() {
println!("{:?}", parse_age(1));
println!("{:?}", parse_age(2));
println!("{:?}", parse_age(9));
}
建议运行:cargo run
期望输出:
Ok(29)
Err("bad age for 2")
Err("user 9 missing")
结合场景再看三个关注点
- None ≠ Err:业务语义不同
?传播缩短样板- 类型迫使处理,不能默默空指针
核心概念与准确模型
enum Option<T> { Some(T), None }
enum Result<T, E> { Ok(T), Err(E) }
常用方法:map、and_then、unwrap_or、ok_or、is_some…
unwrap/expect:开发期或确信不失败时,生产路径慎用。
设计动机
- 消灭隐式 null
- 失败可携带上下文
- 与枚举/泛型无缝
边界与误区
unwrap过多 = 伪装的崩溃驱动开发- 不要用
Option编码真实错误 Result<(), E>表示只关心成败
[!warning] 常见误区:到处 unwrap 库代码应返回 Result;二进制边界再决定日志/退出。
工程实践
- 缺席用 Option,失败用 Result
- 边界转换:
ok_or/map_err - 组合子保持线性可读
- 测试覆盖 None/Err 路径
本节总结
- Option/Result 是核心枚举
- 用类型表达不确定
- 下一篇系统谈错误策略
自测题
- 何时用 Option 而非 Result?
?在返回Option的函数中做什么?
参考答案
- 没有失败原因、只是缺席时。
- 遇到 None 提前返回 None。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| The Book — Option | 官方书 | Option |
| The Book — Error Handling | 官方书 | Result |
| std::option::Option | 标准库 | API |