Enums

Loading concept...

🎯 Rust Enums: The Magic Menu of Choices

Imagine you have a magical menu at a restaurant. Instead of just “food”, you can pick exactly what type: Pizza, Burger, or Salad. That’s what enums do in Rust—they let you say “it’s one of THESE specific things!”


🍕 What is an Enum?

Think of an enum like a box of crayons. You know exactly which colors are inside—Red, Blue, Green. You can’t suddenly have “Purple” unless you add it to the box!

In Rust, an enum is a type that can be one of several specific values called variants.

enum TrafficLight {
    Red,
    Yellow,
    Green,
}

// Using it:
let light = TrafficLight::Red;

Real-life examples:

  • 🚦 Traffic light: Red, Yellow, or Green
  • 🎮 Game direction: Up, Down, Left, Right
  • 📱 Phone status: Ringing, Silent, Vibrate

🎨 Enum Variants: The Different Flavors

Each choice inside an enum is called a variant. Think of variants like different flavors of ice cream in your favorite shop.

enum IceCream {
    Chocolate,    // Variant 1
    Vanilla,      // Variant 2
    Strawberry,   // Variant 3
}

fn main() {
    let my_choice = IceCream::Chocolate;

    // Match to find which flavor!
    match my_choice {
        IceCream::Chocolate => println!("Yum! 🍫"),
        IceCream::Vanilla => println!("Classic! 🍦"),
        IceCream::Strawberry => println!("Fruity! 🍓"),
    }
}

Key Point: Use EnumName::VariantName to pick a specific variant.

graph TD A["IceCream Enum"] --> B["Chocolate"] A --> C["Vanilla"] A --> D["Strawberry"]

📦 Enums with Data: Variants That Carry Gifts!

Here’s where it gets exciting! Variants can carry extra information inside them—like a gift box that contains something special!

Three Types of Data Variants:

1. Tuple-like (unnamed data):

enum Message {
    Move { x: i32, y: i32 },  // Named fields
    Write(String),             // Tuple with String
    ChangeColor(u8, u8, u8),   // RGB values
    Quit,                      // No data
}

let msg = Message::Write(String::from("Hello!"));
let color = Message::ChangeColor(255, 0, 128);

2. Struct-like (named fields):

enum Shape {
    Circle { radius: f64 },
    Rectangle { width: f64, height: f64 },
}

let my_shape = Shape::Circle { radius: 5.0 };

Extracting the data:

match my_shape {
    Shape::Circle { radius } => {
        println!("Circle with radius: {}", radius);
    }
    Shape::Rectangle { width, height } => {
        println!("Rectangle: {}x{}", width, height);
    }
}

Think of it like this:

  • 📧 An envelope (variant) can be empty OR contain a letter (data)
  • 📱 A notification can be “Silent” OR “Alarm(time)” with specific time!

🎁 The Option Enum: Maybe There, Maybe Not!

The Problem: What if something might not exist? Like looking for your friend in a crowd—they might be there, or they might not!

Rust solves this with the Option enum:

enum Option<T> {
    Some(T),  // Something is here!
    None,     // Nothing here!
}

Real example:

fn find_even(num: i32) -> Option<i32> {
    if num % 2 == 0 {
        Some(num)  // Found an even number!
    } else {
        None       // Not even, nothing to return
    }
}

fn main() {
    let result = find_even(4);

    match result {
        Some(n) => println!("Found even: {}", n),
        None => println!("Not even!"),
    }
}
graph TD A["Option"] --> B["Some&#35;40;value&#35;41; ✅"] A --> C["None ❌"] B --> D["The value exists!"] C --> E["Nothing here!"]

Why is this amazing?

  • 🛡️ Forces you to handle “nothing” cases
  • 🚫 No more “null pointer” crashes!
  • ✅ The compiler helps you remember

🧰 Option Combinators: Magic Tools for Options

Instead of always using match, Rust gives you helper methods (combinators) to work with Options easily!

1. unwrap() - Brave but Dangerous!

let x: Option<i32> = Some(5);
let value = x.unwrap();  // Gets 5
// ⚠️ CRASHES if x is None!

2. unwrap_or() - Safe Default

let x: Option<i32> = None;
let value = x.unwrap_or(0);  // Gets 0 (default)

3. map() - Transform the Inside

let x: Option<i32> = Some(5);
let doubled = x.map(|n| n * 2);  // Some(10)

4. and_then() - Chain Operations

fn double_if_positive(n: i32) -> Option<i32> {
    if n > 0 { Some(n * 2) } else { None }
}

let x: Option<i32> = Some(5);
let result = x.and_then(double_if_positive);
// Some(10)

5. is_some() & is_none() - Quick Checks

let x: Option<i32> = Some(5);
if x.is_some() {
    println!("We have a value!");
}

Quick Reference Table:

Method What it does Returns
unwrap() Get value (crashes if None) T
unwrap_or(default) Get value or default T
map(fn) Transform inner value Option
and_then(fn) Chain Option-returning fn Option
is_some() Check if Some bool
is_none() Check if None bool

⚡ The Result Enum: Success or Error!

The Problem: Sometimes things can go wrong! Reading a file might fail. Dividing might hit zero. How do we handle this?

Rust uses the Result enum:

enum Result<T, E> {
    Ok(T),   // Success! Here's your value
    Err(E),  // Oops! Here's the error
}

Real example:

fn divide(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err(String::from("Cannot divide by zero!"))
    } else {
        Ok(a / b)
    }
}

fn main() {
    match divide(10, 2) {
        Ok(result) => println!("Answer: {}", result),
        Err(e) => println!("Error: {}", e),
    }

    match divide(10, 0) {
        Ok(result) => println!("Answer: {}", result),
        Err(e) => println!("Error: {}", e),
    }
}
graph TD A["Result"] --> B["Ok&#35;40;value&#35;41; ✅"] A --> C["Err&#35;40;error&#35;41; ❌"] B --> D["Operation succeeded!"] C --> E["Something went wrong!"]

Result also has Combinators!

// Safe unwrapping
let result: Result<i32, &str> = Ok(10);
let value = result.unwrap_or(0);

// Transform success value
let doubled = result.map(|n| n * 2);  // Ok(20)

// Check status
if result.is_ok() {
    println!("Success!");
}

The ? Operator: Error Shortcut!

Instead of writing match everywhere, use ? to automatically return errors:

fn read_and_double(input: &str) -> Result<i32, String> {
    let num: i32 = input.parse()
        .map_err(|_| String::from("Not a number!"))?;
    Ok(num * 2)
}

The ? means: “If this is an error, return it immediately. Otherwise, continue with the Ok value.”


🎓 Option vs Result: When to Use Which?

Scenario Use This Example
Value might not exist Option Finding item in list
Operation might fail Result Reading a file
“Nothing” is normal Option Optional user bio
“Nothing” is an error Result Parsing user input

Memory trick:

  • Option = “Maybe there’s something?” 🎁❓
  • Result = “Did it work or break?” ✅❌

🚀 You’re Now an Enum Expert!

You learned:

  1. Enums = A type with specific variants
  2. Variants = The different choices in an enum
  3. Enums with Data = Variants carrying extra info
  4. Option = Some or None for optional values
  5. Option Combinators = Helper methods like map, unwrap_or
  6. Result = Ok or Err for operations that might fail

Enums are one of Rust’s superpowers! They help you write safer, cleaner code by making all possibilities explicit. No more hidden surprises! 🎉


Next up: Use these enums in real projects and watch your code become bulletproof! 🛡️

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive Preview

Interactive - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Interactive - Premium Content

Please sign in to view this interactive content and start learning.

Upgrade to Premium to unlock full access to all interactive content.

Stay Tuned!

Interactive content is coming soon.

Cheatsheet Preview

Cheatsheet - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Cheatsheet - Premium Content

Please sign in to view this cheatsheet and start learning.

Upgrade to Premium to unlock full access to all cheatsheets.

Stay Tuned!

Cheatsheet is coming soon.

Quiz Preview

Quiz - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Quiz - Premium Content

Please sign in to view this quiz and test your knowledge.

Upgrade to Premium to unlock full access to all quizzes.

Stay Tuned!

Quiz is coming soon.

Flashcard Preview

Flashcard - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.

Flashcard - Premium Content

Please sign in to view flashcards and reinforce your learning.

Upgrade to Premium to unlock full access to all flashcards.

Stay Tuned!

Flashcards are coming soon.