Thuta Learning
Rust
IntermediateProgrammingbeginner

Enums, match, and Option<T>

What you'll walk away with

  • Explain the core ideas behind Enums, match, and Option<T>
  • Run the sample Rust code and verify its output
  • Apply the technique correctly to the Tutorial Platform and production scenarios

Build the mental model

An enum is a type declaring that a value can be exactly one of several possible variants, and Rust's enums are more powerful than a C-style enum of integer constants — each variant can carry its own data, like `enum Difficulty { Basic, Intermediate, Advanced(String) }`. The `match` expression is the primary tool for handling an enum, and the compiler enforces exhaustiveness — forgetting to handle a variant is a compile error, preventing the classic fall-through bug that a `switch` statement can silently allow. Rust has no null pointer concept at all — to avoid what other languages often call the "billion-dollar mistake" (NullPointerException), the standard library provides an `Option<T>` enum (`Some(T)` or `None`) that makes the possibility of "there might not be a value" explicit in the type system, so the compiler never lets you use the underlying value without unwrapping the `Option<T>` first — you are forced, at compile time, to handle the `None` case. Think of it like a postal mailbox: mail might have arrived (Some) or the box might be empty (None) — you have to check before reaching in, and blindly reaching in assuming mail is there (like a null pointer dereference) is exactly the mistake Rust's `Option<T>` forces you to handle at compile time instead.

Connect it to a real scenario

Define the content analyzer's `Difficulty` as `enum Difficulty { Basic, Intermediate, Advanced }`, replacing Lesson 9's `String` field with this enum, entirely eliminating the possibility of a typo like "Bassic" at the type level. When parsing a tag out of a lesson file, a tag might not be found, so use `fn find_tag(text: &str) -> Option<&str>` as the return type — callers must handle it with `match find_tag(text) { Some(tag) => ..., None => ... }`; assuming a tag exists and unwrapping blindly can panic on the None case. Producing a display string from the Difficulty enum via `match` means the compiler only accepts the code once every variant is handled, so adding a new variant (`Expert`) later automatically flags this `match` for an update.

Try the working example

rust
enum Difficulty {
    Basic,
    Intermediate,
    Advanced,
}

fn label(d: &Difficulty) -> &str {
    match d {
        Difficulty::Basic => "basic",
        Difficulty::Intermediate => "intermediate",
        Difficulty::Advanced => "advanced",
    }
}

fn find_tag(text: &str) -> Option<&str> {
    text.split_whitespace().find(|w| w.starts_with('#'))
}

fn main() {
    println!("{}", label(&Difficulty::Intermediate));
    match find_tag("Rust ownership #systems") {
        Some(tag) => println!("tag found: {tag}"),
        None => println!("no tag found"),
    }
}
You should see
You print "intermediate" and "tag found: #systems".

5-minute try-it

Create `enum ContentKind { Text, Code(String), Diagram }` where the `Code` variant carries a language name — write a function that uses `match` to produce a description string for each variant.

One important caution

Blindly calling `.unwrap()` on an `Option<T>` without handling the None case — only unwrap when you're certain a value exists, or the code can panic at runtime.

Reaching for a `_` wildcard arm in `match` instead of handling every enum variant explicitly — adding a new variant later silently falls into the wildcard, losing the compiler's exhaustiveness check as a safety net.

The Rust Programming Language — Defining an EnumRust

Easy traps

  • Blindly calling `.unwrap()` on an `Option<T>` without handling the None case — only unwrap when you're certain a value exists, or the code can panic at runtime.
  • Reaching for a `_` wildcard arm in `match` instead of handling every enum variant explicitly — adding a new variant later silently falls into the wildcard, losing the compiler's exhaustiveness check as a safety net.
  • Validate sample code in a local or test environment before applying it to a production system.

Exercise

Create `enum ContentKind { Text, Code(String), Diagram }` where the `Code` variant carries a language name — write a function that uses `match` to produce a description string for each variant.

You'll know it worked when: You print "intermediate" and "tag found: #systems".

Enums, match, and Option<T> | Thuta Learning