Advanced Pattern Matching
Destructure Enum
Pull Fields from Variants
Pattern matching can unpack enum variants and bind the fields needed by each arm.
Program
Play the program to choose a command kind and watch the matching arm destructure it.
destructure_enum.rs
Replay: real traced execution (multi-file project)
fn main() {
let kind = 1;
let command = make_command(kind);
let text = describe(command);
println!("{text}");
}
enum Command {
Move { x: i32, y: i32 },
Wait(i32),
Quit,
}
fn make_command(kind: i32) -> Command {
match kind {
1 => Command::Move { x: 3, y: 4 },
2 => Command::Wait(5),
_ => Command::Quit,
}
}
fn describe(command: Command) -> String {
match command {
Command::Move { x, y } => format!("move:{x},{y}"),
Command::Wait(seconds) => format!("wait:{seconds}"),
Command::Quit => "quit".to_string(),
}
}
fn main() {
let kind = 2;
let command = make_command(kind);
let text = describe(command);
println!("{text}");
}
enum Command {
Move { x: i32, y: i32 },
Wait(i32),
Quit,
}
fn make_command(kind: i32) -> Command {
match kind {
1 => Command::Move { x: 3, y: 4 },
2 => Command::Wait(5),
_ => Command::Quit,
}
}
fn describe(command: Command) -> String {
match command {
Command::Move { x, y } => format!("move:{x},{y}"),
Command::Wait(seconds) => format!("wait:{seconds}"),
Command::Quit => "quit".to_string(),
}
}
fn main() {
let kind = 3;
let command = make_command(kind);
let text = describe(command);
println!("{text}");
}
enum Command {
Move { x: i32, y: i32 },
Wait(i32),
Quit,
}
fn make_command(kind: i32) -> Command {
match kind {
1 => Command::Move { x: 3, y: 4 },
2 => Command::Wait(5),
_ => Command::Quit,
}
}
fn describe(command: Command) -> String {
match command {
Command::Move { x, y } => format!("move:{x},{y}"),
Command::Wait(seconds) => format!("wait:{seconds}"),
Command::Quit => "quit".to_string(),
}
}
kind ← 1
1fn main() {2 let kin→ 1d = 1; //@kind=1, 2, 33 let command = make_command(kin1d);4 let text = describe(command);command ← (empty)
2let kind = 1; //@kind=1, 2, 33let comman→ (empty)d = make_command(kin1d);4let text = describe(comman(empty)d);5println!("{text}");text ← "move:3,4"
3 let command = make_command(kind);4 let tex→ "move:3,4"t = describe(comman(empty)d);5 println!("{text}");6}outputmove:3,4
kind ← 2
1fn main() {2 let kin→ 2d = 2;3 let command = make_command(kin2d);4 let text = describe(command);command ← (empty)
2let kind = 2;3let comman→ (empty)d = make_command(kin2d);4let text = describe(comman(empty)d);5println!("{text}");text ← "wait:5"
3 let command = make_command(kind);4 let tex→ "wait:5"t = describe(comman(empty)d);5 println!("{text}");6}outputwait:5
kind ← 3
1fn main() {2 let kin→ 3d = 3;3 let command = make_command(kin3d);4 let text = describe(command);command ← (empty)
2let kind = 3;3let comman→ (empty)d = make_command(kin3d);4let text = describe(comman(empty)d);5println!("{text}");text ← "quit"
3 let command = make_command(kind);4 let tex→ "quit"t = describe(comman(empty)d);5 println!("{text}");6}outputquit
enum variant
`Command::Move { x, y }` matches one variant and binds its fields.
tuple variant
`Command::Wait(seconds)` binds the single value inside a tuple-like variant.
ownership
`describe` takes ownership of the command and consumes it while matching.