Generic enums let you create flexible types that can hold different kinds of data. This helps you reuse code and handle many situations with one design.
Generic enums in Rust
enum EnumName<T> {
Variant1(T),
Variant2,
}The <T> after the enum name means it uses a generic type called T.
Each variant can use T to hold data of that generic type.
enum Option<T> {
Some(T),
None,
}T or an error value E.enum Result<T, E> {
Ok(T),
Err(E),
}enum Container<T> {
Item(T),
Empty,
}This program shows a generic enum Container holding different types: a number, a text, and an empty value. It prints each one using pattern matching.
enum Container<T> { Item(T), Empty, } fn main() { let number = Container::Item(42); let text = Container::Item("hello"); let empty: Container<i32> = Container::Empty; match number { Container::Item(value) => println!("Number: {}", value), Container::Empty => println!("No number"), } match text { Container::Item(value) => println!("Text: {}", value), Container::Empty => println!("No text"), } match empty { Container::Item(value) => println!("Empty has value: {}", value), Container::Empty => println!("Empty container"), } }
Generic enums help avoid writing many similar enums for different types.
You can use multiple generic types by adding more letters like <T, U>.
Pattern matching works the same way with generic enums.
Generic enums let you create flexible types that work with any data type.
They help reuse code and handle many cases with one enum.
Use pattern matching to get the data inside generic enums.
Practice
generic enums in Rust?Solution
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.Step 2: Identify the benefit
This means you can reuse the same enum for many data types without rewriting it for each type.Final Answer:
They allow enums to hold different types of data without rewriting code. -> Option AQuick Check:
Generic enums = flexible data types [OK]
- Thinking generic enums improve speed
- Believing they auto-generate functions
- Assuming they limit data types
Option with a type parameter T?Solution
Step 1: Recall generic enum syntax
Generic enums declare the type parameter after the enum name, likeenum Name<T>.Step 2: Check variant definitions
Variants can use the generic typeTdirectly, e.g.,Some(T). TheNonevariant has no data.Final Answer:
enum Option<T> { Some(T), None } -> Option AQuick Check:
Generic param after enum name = enum Option<T> { Some(T), None } [OK]
- Putting
<T>after variant name - Adding data to
Nonevariant - Omitting generic parameter after enum name
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),
}
}Solution
Step 1: Understand the enum and value
The enumResulthas two variants:Okwith typeTandErrwith typeE. The variablevalueisResult::Ok(10).Step 2: Match arms and output
The match checks ifvalueisOkorErr. Since it isOk(10), it printsValue: 10.Final Answer:
Value: 10 -> Option DQuick Check:
Match Ok(10) prints Value: 10 [OK]
- Confusing Ok and Err variants
- Expecting error output for Ok variant
- Thinking code won't compile
enum Wrapper<T> {
Value(T),
}
fn main() {
let w: Wrapper = Wrapper::Value(5);
}Solution
Step 1: Check enum declaration and usage
The enumWrapperis generic overT. When creatingw, the type parameter is missing.Step 2: Understand Rust's type inference rules
Rust requires specifying the type parameter explicitly or letting it infer from context. Here,wis declared without<i32>, so it causes an error.Final Answer:
Missing type parameter <i32> when declaring w. -> Option CQuick Check:
Generic enum needs type parameter specified [OK]
- Omitting generic type parameter
- Thinking enum variants can't hold generics
- Adding unnecessary lifetime parameters
enum Container<T> {
Single(T),
Multiple(Vec<T>),
}Which code correctly creates a
Container holding multiple String values and prints each string?Solution
Step 1: Check type correctness in creation
The enumContainerexpectsVec<T>forMultiple. Usingvec!["a".to_string(), "b".to_string()]creates aVec<String>, matchingContainer<String>.Step 2: Verify pattern matching and printing
Theif letcorrectly matchesContainer::Multiple(v)and iterates overvto print each string.Final Answer:
Code correctly creates and prints the strings. -> Option BQuick 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]
- Missing generic type annotation
- Using wrong variant for multiple values
- Using string slices instead of String objects
Ready to prove it?
Pass the test and this pattern moves unknown
