Generic enums
Goal of This Episode
Learn to define enums with type parameters.
Concept
Last episode was generic structs; this one is generic enums. The idea is exactly the same — add <T> after the enum name, and the data variants carry can be of any type.
Defining a Generic enum
Suppose we want a “maybe there’s a value” type — it might hold something, or be empty:
enum Maybe<T> {
Something(T),
Nothing,
}
fn main() {}
Something(T) carries a value of type T; Nothing carries nothing.
Generic enums can have multiple type parameters too. Say, an “either-or” type:
enum Either<L, R> {
Left(L),
Right(R),
}
fn main() {}
An Either<L, R> is either Left(L) or Right(R) — the two types fully independent.
Example Code
// Our own generic enum
#[derive(Debug)]
enum Maybe<T> {
Something(T),
Nothing,
}
// A generic enum with two type parameters
#[derive(Debug)]
enum Either<L, R> {
Left(L),
Right(R),
}
fn main() {
let a: Maybe<i32> = Maybe::Something(42);
let b: Maybe<i32> = Maybe::Nothing;
println!("{:?}", a);
println!("{:?}", b);
// Extracting the value with match
match a {
Maybe::Something(val) => println!("There's something inside: {}", val),
Maybe::Nothing => println!("Empty"),
}
// Two type parameters
let x: Either<i32, &str> = Either::Left(100);
let y: Either<i32, &str> = Either::Right("hello");
println!("{:?}", x);
println!("{:?}", y);
}
Recap
enums can take type parameters too:enum Maybe<T> { ... }.- The data a variant carries can be generalized with
T. - Multiple type parameters are allowed:
enum Either<L, R> { Left(L), Right(R) }. - The standard library has many important generic
enums — we’ll meet them in due course.