Bird
Raised Fist0
Rustprogramming~10 mins

Generic enums in Rust - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Generic enums
Define generic enum with type parameter T
↓
Create enum instance with specific type
↓
Match on enum variant
↓
Variant A
↓
Use value of type T
↓
End of match
This flow shows defining a generic enum, creating instances with specific types, and matching on variants to use the contained values.
Execution Sample
Rust
enum Option<T> {
    Some(T),
    None,
}

fn main() {
    let x: Option<i32> = Option::Some(5);
    match x {
        Option::Some(val) => println!("Value: {}", val),
        Option::None => println!("No value"),
    }
}
Defines a generic enum Option with type T, creates an instance with i32, and matches to print the value.
Execution Table
StepActionEvaluationResult
1Define enum Option<T>Generic enum with variants Some(T) and NoneEnum ready for use
2Create x = Option::Some(5)x is Option<i32> with Some(5)x holds Some(5)
3Match on xx is Some(5)Go to Some branch
4Print valueval = 5Output: Value: 5
5End matchNo more variantsMatch complete
💡 Match ends after handling Some variant with value 5
Variable Tracker
VariableStartAfter Step 2After Step 3Final
xuninitializedSome(5)Some(5)Some(5)
valN/AN/A55
Key Moments - 3 Insights
Why do we write Option<T> instead of just Option?
Option<T> means the enum can hold any type T. This is shown in step 1 of the execution_table where the enum is defined with a generic type parameter T.
How does Rust know what type T is when we create x?
In step 2, we create x as Option<i32> by specifying the type. This tells Rust that T is i32 for this instance.
What happens if x is Option::None?
In the match (step 3), if x was None, the code would go to the None branch and print 'No value' instead of 'Value: 5'.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of x after step 2?
ASome(5)
BNone
CUninitialized
D5
💡 Hint
Check the 'After Step 2' column for variable x in variable_tracker.
At which step does the program print the output?
AStep 3
BStep 4
CStep 2
DStep 5
💡 Hint
Look at the 'Action' and 'Result' columns in execution_table for printing.
If we changed x to Option::None, which step's result would change?
AStep 2
BStep 3
CStep 4
DStep 5
💡 Hint
Consider the match branches in step 3 and what is printed in step 4.
Concept Snapshot
Generic enums allow defining enums with a type parameter T.
You create instances by specifying the concrete type, e.g., Option<i32>.
Match on enum variants to access the contained value of type T.
This enables flexible, reusable enum definitions.
Full Transcript
This example shows how to define a generic enum Option with a type parameter T. We create an instance x of type Option<i32> holding the value Some(5). Then we match on x to check which variant it is. Since x is Some(5), we print the value 5. The execution table traces each step: defining the enum, creating x, matching on x, printing the value, and ending the match. The variable tracker shows how x and val change during execution. Key moments clarify why we use generics, how Rust infers types, and what happens if the enum is None. The quiz tests understanding of variable values and match behavior. This helps beginners see how generic enums work step-by-step in Rust.

Practice

(1/5)
1. What is the main benefit of using generic enums in Rust?
easy
A. They allow enums to hold different types of data without rewriting code.
B. They make enums run faster by using less memory.
C. They automatically generate functions for enums.
D. They restrict enums to only one data type.

Solution

  1. Step 1: Understand what generic enums do

    Generic enums let you define an enum that can hold different types of data by using type parameters.
  2. Step 2: Identify the benefit

    This means you can reuse the same enum for many data types without rewriting it for each type.
  3. Final Answer:

    They allow enums to hold different types of data without rewriting code. -> Option A
  4. Quick Check:

    Generic enums = flexible data types [OK]
Hint: Generic enums = one enum, many data types [OK]
Common Mistakes:
  • Thinking generic enums improve speed
  • Believing they auto-generate functions
  • Assuming they limit data types
2. Which of the following is the correct syntax to define a generic enum named Option with a type parameter T?
easy
A. enum Option<T> { Some(T), None }
B. enum Option { Some<T>(T), None }
C. enum Option<T> { Some, None(T) }
D. enum Option { Some(T), None }

Solution

  1. Step 1: Recall generic enum syntax

    Generic enums declare the type parameter after the enum name, like enum Name<T>.
  2. Step 2: Check variant definitions

    Variants can use the generic type T directly, e.g., Some(T). The None variant has no data.
  3. Final Answer:

    enum Option<T> { Some(T), None } -> Option A
  4. Quick Check:

    Generic param after enum name = enum Option<T> { Some(T), None } [OK]
Hint: Generic param goes after enum name, not variant [OK]
Common Mistakes:
  • Putting <T> after variant name
  • Adding data to None variant
  • Omitting generic parameter after enum name
3. What will be the output of this Rust code?
enum Result {
    Ok(T),
    Err(E),
}

fn main() {
    let value: Result = Result::Ok(10);
    match value {
        Result::Ok(v) => println!("Value: {}", v),
        Result::Err(e) => println!("Error: {}", e),
    }
}
medium
A. Compilation error
B. Error: 10
C. Value: Err
D. Value: 10

Solution

  1. Step 1: Understand the enum and value

    The enum Result has two variants: Ok with type T and Err with type E. The variable value is Result::Ok(10).
  2. Step 2: Match arms and output

    The match checks if value is Ok or Err. Since it is Ok(10), it prints Value: 10.
  3. Final Answer:

    Value: 10 -> Option D
  4. Quick Check:

    Match Ok(10) prints Value: 10 [OK]
Hint: Match enum variant to print correct value [OK]
Common Mistakes:
  • Confusing Ok and Err variants
  • Expecting error output for Ok variant
  • Thinking code won't compile
4. Identify the error in this generic enum usage:
enum Wrapper<T> {
    Value(T),
}

fn main() {
    let w: Wrapper = Wrapper::Value(5);
}
medium
A. Cannot use Wrapper::Value to create a value.
B. Enum variants cannot hold generic types.
C. Missing type parameter <i32> when declaring w.
D. The enum must have a lifetime parameter.

Solution

  1. Step 1: Check enum declaration and usage

    The enum Wrapper is generic over T. When creating w, the type parameter is missing.
  2. Step 2: Understand Rust's type inference rules

    Rust requires specifying the type parameter explicitly or letting it infer from context. Here, w is declared without <i32>, so it causes an error.
  3. Final Answer:

    Missing type parameter <i32> when declaring w. -> Option C
  4. Quick Check:

    Generic enum needs type parameter specified [OK]
Hint: Always specify generic type when declaring variables [OK]
Common Mistakes:
  • Omitting generic type parameter
  • Thinking enum variants can't hold generics
  • Adding unnecessary lifetime parameters
5. Given this generic enum:
enum Container<T> {
    Single(T),
    Multiple(Vec<T>),
}

Which code correctly creates a Container holding multiple String values and prints each string?
hard
A. let c: Container = Container::Multiple(vec!["a", "b"]); match c { Container::Multiple(v) => for s in v { println!("{}", s); }, _ => (), }
B. let c = Container::Multiple(vec!["a".to_string(), "b".to_string()]); if let Container::Multiple(v) = c { for s in v { println!("{}", s); } }
C. let c = Container::Single(vec!["a".to_string(), "b".to_string()]); match c { Container::Multiple(v) => for s in v { println!("{}", s); }, _ => (), }
D. let c = Container::Multiple(vec!["a", "b"]); if let Container::Multiple(v) = c { for s in v { println!("{}", s); } }

Solution

  1. Step 1: Check type correctness in creation

    The enum Container expects Vec<T> for Multiple. Using vec!["a".to_string(), "b".to_string()] creates a Vec<String>, matching Container<String>.
  2. Step 2: Verify pattern matching and printing

    The if let correctly matches Container::Multiple(v) and iterates over v to print each string.
  3. Final Answer:

    Code correctly creates and prints the strings. -> Option B
  4. Quick Check:

    Correct generic type and pattern matching = let c = Container::Multiple(vec!["a".to_string(), "b".to_string()]); if let Container::Multiple(v) = c { for s in v { println!("{}", s); } } [OK]
Hint: Use to_string() for String vectors and match variants properly [OK]
Common Mistakes:
  • Missing generic type annotation
  • Using wrong variant for multiple values
  • Using string slices instead of String objects
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard