Enums and pattern matching: explicit state instead of ad hoc shape
Model variant-rich data directly with enums and handle it exhaustively with match expressions.
by the end of this lesson you can
- →Models the variant as an enum rather than a string tag
- →Uses match instead of string comparisons
- →Makes data carried by each variant explicit
Overview
Python developers often model state with classes, dictionaries, or string tags. Rust gives you enums and pattern matching, which make legal states and required handling visible in the type system.
In Python, you often
represent variants with dictionaries, classes, or stringly-typed flags and trust conventions to keep cases aligned.
In Rust, the common pattern is
to express variants directly as enum cases and use match to handle them exhaustively.
why this difference matters
This reduces impossible states and shifts branching logic from convention into the compiler's field of view.
Python
status = {"kind": "ok", "value": 42}
if status["kind"] == "ok":
print(status["value"])Rust
enum Status {
Ok(i32),
Missing,
}
match status {
Status::Ok(value) => println!("{}", value),
Status::Missing => println!("missing"),
}Deeper comparison
Python version
event = {"type": "click", "x": 10, "y": 20}
if event["type"] == "click":
handle_click(event["x"], event["y"])Rust version
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
}
match event {
Event::Click { x, y } => handle_click(x, y),
Event::KeyPress(key) => handle_key(key),
}Reflect
What gets clearer when valid states are represented explicitly as enum variants instead of conventions in data structures?
what a strong answer notices
A strong answer mentions exhaustive handling, impossible-state reduction, and clearer branching logic at the use site.
Rewrite
Rewrite this Python tagged-data example into a Rust enum plus match expression.
Rewrite this Python
response = {"kind": "error", "message": "timeout"}what good looks like
- Models the variant as an enum rather than a string tag
- Uses match instead of string comparisons
- Makes data carried by each variant explicit
Practice
Design a Rust enum for a background job that can be queued, running, completed, or failed with an error message.
success criteria
- Represents state transitions as explicit variants
- Uses carried data only where needed
- Shows how pattern matching would read that state safely
Common mistakes
- Recreating tagged dictionaries instead of using enums.
- Using strings to represent cases the type system could encode directly.
- Treating match as a verbose if/else rather than a modeling tool.
takeaways
- ●This reduces impossible states and shifts branching logic from convention into the compiler's field of view.
- ●A strong answer mentions exhaustive handling, impossible-state reduction, and clearer branching logic at the use site.
- ●Represents state transitions as explicit variants