简洁的分支判断

你对上一练习的解答可能如下所示:

#![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 letlet/else都是惯用的Rust构造。根据需要使用它们来提高代码的可读性,但不要过度:当你需要时,match总是在那里。

参考资料

  • 本节练习位于 exercises/05_ticket_v2/04_if_let