变体载荷

你可以定义更丰富的枚举,其中变体会携带数据。然后,你可以使用 match 语句从每个变体中提取数据:

enum WebEvent {
    PageLoad,                 // Variant without payload
    KeyPress(char),           // Tuple struct variant
    Click { x: i64, y: i64 }, // Full struct variant
}

#[rustfmt::skip]
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad       => println!("page loaded"),
        WebEvent::KeyPress(c)    => println!("pressed '{c}'"),
        WebEvent::Click { x, y } => println!("clicked at x={x}, y={y}"),
    }
}

fn main() {
    let load = WebEvent::PageLoad;
    let press = WebEvent::KeyPress('x');
    let click = WebEvent::Click { x: 20, y: 80 };

    inspect(load);
    inspect(press);
    inspect(click);
}
  • 枚举变体中的值只有在被模式匹配后,才可访问。模式将引用绑定到 => 之后的“match 分支”中的字段。
    • 表达式会从上到下与模式匹配。没有像 C 或 C++ 中那样的跳转。
    • 匹配表达式拥有一个值。值是 match 分支中被执行的最后一个表达式。
    • 从顶部开始,查找与该值匹配的模式,然后沿箭头运行代码。一旦找到匹配,我们便会停止。
  • 展示搜索不详尽时会发生的情况。请注意 Rust 编译器的优势,即确认所有情况何时都得到了处理。
  • match 会检查 enum 中的隐藏的判别字段。
  • 可以通过调用 std::mem::discriminant() 来检索判别
    • 这很有用,例如如果为结构体实现 PartialEq,比较字段值不会影响等式。
  • WebEvent::Click { ... } 与含顶层 struct Click { ... }WebEvent::Click(Click) 不完全相同。例如,内嵌版本无法实现 trait。