Rust Result 与 Option 错误处理指南
wxk1991 Lv5

Rust Result 与 Option 错误处理指南

Rust 没有传统意义上的异常机制。它把“可能失败”和“可能为空”都放进类型系统里,让你在编译期就必须面对这些情况。


一、Option 表达可能没有值

当一个值可能不存在时,Rust 使用 Option<T>

1
2
3
4
5
6
7
fn find_user(id: u64) -> Option<String> {
if id == 1 {
Some(String::from("Alice"))
} else {
None
}
}

调用方必须处理 SomeNone

1
2
3
4
match find_user(1) {
Some(name) => println!("{}", name),
None => println!("user not found"),
}

这比返回 null 更安全,因为编译器会提醒你处理空值。


二、Result 表达可能失败

当操作可能失败,并且需要说明失败原因时,使用 Result<T, E>

1
2
3
4
5
use std::fs;

fn read_config() -> Result<String, std::io::Error> {
fs::read_to_string("config.toml")
}

Ok 表示成功,Err 表示失败。


三、问号运算符

实际项目里不可能每一步都写完整 match? 可以把错误向上传递:

1
2
3
4
fn load_name() -> Result<String, std::io::Error> {
let content = std::fs::read_to_string("name.txt")?;
Ok(content.trim().to_string())
}

如果读取失败,函数会立即返回错误;如果成功,就继续向下执行。


四、什么时候 unwrap

unwrap 会在失败时直接 panic:

1
let port = "8080".parse::<u16>().unwrap();

它适合测试、示例代码、确定不会失败的初始化场景。不建议在 Web 服务、CLI 工具核心流程里大量使用。


五、推荐实践

业务代码里可以这样分层:

  • 底层函数返回清晰的 Result
  • 中间层用 ? 传递错误
  • 最外层统一转换成日志、HTTP 响应或命令行输出

Rust 的错误处理看起来啰嗦,但它逼你把失败路径设计清楚。项目越大,这种清楚越值钱。