外观
第 1 节:Option 方法宝库
Option 不只是 match 拆信封的对象——它自带一整套"有值/没值"的工具,让代码从"两层 match"变成"一行方法"。高频六件套:
map:有值就加工 ⭐
rust
let text = Some(String::from("42"));
let parsed = text.map(|s| s.parse::<u32>().unwrap_or(0));
// Some(42)map 是"有值就加工,没值就原样放行":Some(值) → Some(加工后),None → None。和 Result 的 map 一个脾气(第 2 节)。
and_then:有值,且下一步也可能没有 ⭐
rust
let text = Some(String::from("abc"));
let number = text.and_then(|s| s.parse::<u32>().ok());
// None(abc 解析失败)
let text = Some(String::from("42"));
let number = text.and_then(|s| s.parse::<u32>().ok());
// Some(42)map 和 and_then 的区别:加工完是 T 用 map,加工完还是 Option<T> 用 and_then。链条式"有值才继续"的场景,and_then 是主角——比如"找配置 → 解析数字",每步都可能没有。
unwrap_or / unwrap_or_else:没有就用备胎 ⭐
rust
let port = std::env::var("PORT").ok().unwrap_or_else(|| String::from("8080"));
// 环境变量没有 PORT?用默认 8080unwrap_or(备胎):备胎是已经算好的值unwrap_or_else(闭包):备胎是用到才现算的——备胎昂贵时用这个,省一次计算
常见误用:拿它当 unwrap 用,忘了备胎——unwrap_or 不会炸,但会悄悄给出错误的值。
take:掏出来,留下 None ⭐
rust
let mut slot: Option<String> = Some(String::from("贵重物品"));
let taken = slot.take();
// taken = Some("贵重物品"),slot = None"从结构体里搬走一个字段"的神器(第 8 章雷区 7 预告过):把 Option 字段的值掏走,原地留下 None——结构体还能继续用,不会触发 E0505。
rust
struct Config {
token: Option<String>,
}
let mut config = Config { token: Some(String::from("secret")) };
if let Some(token) = config.token.take() {
// token 拿走了,config.token 变成 None,config 还能用
}filter:有值且符合条件 ✨
rust
let score = Some(95);
score.filter(|s| *s >= 90); // Some(95)——符合条件,放行
score.filter(|s| *s < 90); // None——不符合,变成没有"有值,但值不合格就当作没有"——比如"找到用户,但必须已激活"。
is_some / is_none:只问有没有 ⭐
rust
if score.is_some() { /* 有值 */ }
if value.is_none() { /* 没有 */ }记忆口诀
map 加工, and_then 接力, unwrap_or 备胎, take 掏走, filter 把关, is_some 问一句。 每个方法问自己三个问题:有值怎么办?没值怎么办?值要不要保留?——答完,代码就出来了。
常见误用
过度 match:只想要"有值就干点什么"却写了完整 match——if let 或 map 更短:
rust
// 啰嗦
match opt {
Some(v) => println!("{}", v),
None => {}
}
// 一行
if let Some(v) = opt { println!("{}", v); }