Variant Payloads
You can define richer enums where the variants carry data. You can then use the
match
statement to extract the data from each variant:
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); }
- The values in the enum variants can only be accessed after being pattern matched. The pattern binds references to the fields in the “match arm” after the
=>
.- The expression is matched against the patterns from top to bottom. There is no fall-through like in C or C++.
- The match expression has a value. The value is the last expression in the match arm which was executed.
- Starting from the top we look for what pattern matches the value then run the code following the arrow. Once we find a match, we stop.
- Demonstrate what happens when the search is inexhaustive. Note the advantage the Rust compiler provides by confirming when all cases are handled.
match
inspects a hidden discriminant field in theenum
.- It is possible to retrieve the discriminant by calling
std::mem::discriminant()
- This is useful, for example, if implementing
PartialEq
for structs where comparing field values doesn’t affect equality.
- This is useful, for example, if implementing
WebEvent::Click { ... }
is not exactly the same asWebEvent::Click(Click)
with a top levelstruct Click { ... }
. The inlined version cannot implement traits, for example.