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

结合场景再看三个关注点

  1. None ≠ Err:业务语义不同
  2. ? 传播缩短样板
  3. 类型迫使处理,不能默默空指针

核心概念与准确模型

enum Option<T> { Some(T), None }
enum Result<T, E> { Ok(T), Err(E) }

常用方法:mapand_thenunwrap_orok_oris_some
unwrap/expect:开发期或确信不失败时,生产路径慎用。

设计动机

  • 消灭隐式 null
  • 失败可携带上下文
  • 与枚举/泛型无缝

边界与误区

  • unwrap 过多 = 伪装的崩溃驱动开发
  • 不要用 Option 编码真实错误
  • Result<(), E> 表示只关心成败

[!warning] 常见误区:到处 unwrap 库代码应返回 Result;二进制边界再决定日志/退出。

工程实践

  1. 缺席用 Option,失败用 Result
  2. 边界转换:ok_or / map_err
  3. 组合子保持线性可读
  4. 测试覆盖 None/Err 路径

本节总结

  • Option/Result 是核心枚举
  • 用类型表达不确定
  • 下一篇系统谈错误策略

自测题

  1. 何时用 Option 而非 Result?
  2. ? 在返回 Option 的函数中做什么?
参考答案
  1. 没有失败原因、只是缺席时。
  2. 遇到 None 提前返回 None。

延伸阅读与资料来源

资料类型支撑内容
The Book — Option官方书Option
The Book — Error Handling官方书Result
std::option::Option标准库API
创建于 2026/7/15 更新于 2026/7/15