if let 能让我们通过一种不那么烦琐的语法结合使用 if 与 let,并处理那些只用关心某一种匹配而忽略其他匹配的情况。思考一下 示例6-6 中的程序,它会匹配一个 Option<u8> 的值,并只在值为 3 时执行代码。
// 示例6-6:这里的match只在值为Some(3)时执行特定的代码
let some_u8_value = Some(0u8);
match some_u8_value {
Some(3) => println!("three"),
_ => (),
}
我们想要对 Some(3) 的匹配执行某些操作,并忽略其他 Some<u8> 或 None 值。为了满足 match 表达式穷尽性的需求,我们不得不在处理完这唯一的变体后额外加上一句 _ => (),这显得十分多余。
不过,我们可以使用 if let 以一种更加简短的方式实现这段代码。下面的代码与 示例6-6 中的 match 拥有完全一致的行为:
if let Some(3) = some_u8_value {
println!("three");
}
这里的 if let 语法使用一对以 = 隔开的模式与表达式。它们所起的作用与 match 中的完全相同,表达式对应 match 中的输入,而模式则对应第一个分支。
使用 if let 意味着你可以编写更少的代码,使用更少的缩进,使用更少的模板代码。但是,你也放弃了 match 所附带的穷尽性检查。
究竟应该使用 match 还是 if let 取决于你当时所处的环境,这是一个在代码简捷性与穷尽性检查之间取舍的过程。
换句话说,你可以将 if let 视作 match 的语法糖。它只在值满足某一特定模式时运行代码,而忽略其他所有的可能性。
我们还可以在 if let 中搭配使用 else。else 所关联的代码块在 if let 语句中扮演的角色,就如同 match 中 _ 模式所关联的代码块一样。
还记得我们曾经在 示例6-4 中定义的 Coin 枚举吗?里面的 Quarter 变体包含了一个 UsState 值。
假如我们想要在打印25美分硬币中的信息的同时,对处理过的所有非25美分的硬币进行计数,我们就可以像下面一样使用 match 表达式:
let mut count = 0;
match coin {
Coin::Quarter(state) => println!("State quarter from {:?}!", state),
_ => count += 1,
}
或者我们可以像下面这样使用 if let 与 else 表达式:
let mut count = 0;
if let Coin::Quarter(state) = coin {
println!("State quarter from {:?}!", state);
} else {
count += 1;
}
如果你在编写程序的过程中,觉得在某些情形下使用 match 会过分烦琐,要记得在Rust工具箱中还有 if let 的存在。