Files
100-exercises-to-learn-rust/book/src/05_ticket_v2/02_match.md
2025-09-03 08:28:37 -07:00

2.3 KiB
Raw Blame History

match

You may be wondering—what can you actually do with an enum?
The most common operation is to match on it.

enum Status {
    ToDo,
    InProgress,
    Done
}

impl Status {
    fn is_done(&self) -> bool {
        match self {
            Status::Done => true,
            // The `|` operator lets you match multiple patterns.
            // It reads as "either `Status::ToDo` or `Status::InProgress`".
            Status::InProgress | Status::ToDo => false
        }
    }
}

A match statement that lets you compare a Rust value against a series of patterns.
You can think of it as a type-level if. If status is a Done variant, execute the first block; if its a InProgress or ToDo variant, execute the second block.

Exhaustiveness

Theres one key detail here: match is exhaustive. You must handle all enum variants.
If you forget to handle a variant, Rust will stop you at compile-time with an error.

E.g. if we forget to handle the ToDo variant:

match self {
    Status::Done => true,
    Status::InProgress => false,
}

the compiler will complain:

error[E0004]: non-exhaustive patterns: `ToDo` not covered
 --> src/main.rs:5:9
  |
5 |     match status {
  |     ^^^^^^^^^^^^ pattern `ToDo` not covered

This is a big deal!
Codebases evolve over time—you might add a new status down the line, e.g. Blocked. The Rust compiler will emit an error for every single match statement thats missing logic for the new variant. Thats why Rust developers often sing the praises of “compiler-driven refactoring”—the compiler tells you what to do next, you just have to fix what it reports.

Catch-all

If you dont care about one or more variants, you can use the _ pattern as a catch-all:

match status {
    Status::Done => true,
    _ => false
}

The _ pattern matches anything that wasnt matched by the previous patterns.

By using this catch-all pattern, you wont get the benefits of compiler-driven refactoring. If you add a new enum variant, the compiler wont tell you that youre not handling it.

If youre keen on correctness, avoid using catch-alls. Leverage the compiler to re-examine all matching sites and determine how new enum variants should be handled.