Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.