简洁的分支判断
你对上一练习的解答可能如下所示:
#![allow(unused)] fn main() { impl Ticket { pub fn assigned_to(&self) -> &str { match &self.status { Status::InProgress { assigned_to } => assigned_to, Status::Done | Status::ToDo => { panic!("Only `In-Progress` tickets can be assigned to someone"), } } } } }
你只关心Status::InProgress
变体。真的需要匹配所有其他变体吗?
有新的构造来帮忙!
if let
if let
构造允许你仅匹配枚举的一个变体,而不必处理所有其他变体。
你可以这样使用if let
来简化assigned_to
方法:
#![allow(unused)] fn main() { impl Ticket { pub fn assigned_to(&self) -> &str { if let Status::InProgress { assigned_to } = &self.status { assigned_to } else { panic!("Only `In-Progress` tickets can be assigned to someone"); } } } }
let/else
如果else
分支旨在提前返回(恐慌也算作提前返回!),你可以使用let/else
构造:
#![allow(unused)] fn main() { impl Ticket { pub fn assigned_to(&self) -> &str { let Status::InProgress { assigned_to } = &self.status else { panic!("Only `In-Progress` tickets can be assigned to someone"); }; assigned_to } } }
它允许你分配解构后的变量,而不会引起任何“向右偏移”,即变量在与其前面代码相同缩进级别被赋值。
样式
if let
和let/else
都是惯用的Rust构造。根据需要使用它们来提高代码的可读性,但不要过度:当你需要时,match
总是在那里。
参考资料
- 本节练习位于
exercises/05_ticket_v2/04_if_let