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.

kind
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(),
    }
}
  1. kind ← 1

    1fn main() {2    let kin→ 1d = 1; //@kind=1, 2, 33    let command = make_command(kin1d);4    let text = describe(command);
  2. command ← (empty)

    2let kind = 1; //@kind=1, 2, 33let comman→ (empty)d = make_command(kin1d);4let text = describe(comman(empty)d);5println!("{text}");
  3. 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
  1. kind ← 2

    1fn main() {2    let kin→ 2d = 2;3    let command = make_command(kin2d);4    let text = describe(command);
  2. command ← (empty)

    2let kind = 2;3let comman→ (empty)d = make_command(kin2d);4let text = describe(comman(empty)d);5println!("{text}");
  3. 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
  1. kind ← 3

    1fn main() {2    let kin→ 3d = 3;3    let command = make_command(kin3d);4    let text = describe(command);
  2. command ← (empty)

    2let kind = 3;3let comman→ (empty)d = make_command(kin3d);4let text = describe(comman(empty)d);5println!("{text}");
  3. 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.