liveBook · Manning

Enum

As explained in Learn Rust in a Month of Lunches

An enum is a Rust user-defined type whose values are one of a fixed set of named variants, optionally carrying associated data.

An enum is a type for a choice: a value is one of its named variants. Use a struct when you need several pieces together; use an enum when you need one option from several. A struct can also have an enum as a field—for example, a country can have one climate. section 4.1 section 4.1.2

Declare and choose a variant

Write `enum ThingsInTheSky { Sun, Stars }` to define two choices. Write `ThingsInTheSky::Sun` to select one. The names after `::` are called variants. section 4.1.2

enum ThingsInTheSky {
    Sun,
    Stars,
}
 
fn create_skystate(time: i32) -> ThingsInTheSky {    #1
    match time {
        6..=18 => ThingsInTheSky::Sun,
        _ => ThingsInTheSky::Stars,
    }
}
 
fn check_skystate(state: &ThingsInTheSky) {          #2
    match state {
        ThingsInTheSky::Sun => println!("I can see the sun!"),
        ThingsInTheSky::Stars => println!("I can see the stars!")
    }
}
 
fn main() {
    let time = 8;                                    #3
    let skystate = create_skystate(time);            #4
    check_skystate(&skystate);
}

Follow the time into `create_skystate`: its `match` returns one variant. A second `match` checks which variant was returned and prints the corresponding message. section 4.1.2

Variants can carry data as well as identify a choice. For example, `Sun(String)` and `Stars(String)` each carry a description. When matching, a name inside the variant pattern gives you that description to print. If repeated `Mood::` prefixes feel long, `use Mood::*` lets you write the variant names alone within that scope. section 4.1.2

enum Number {
    U32(u32),
    I32(i32),
}
 
fn get_number(input: i32) -> Number {
    let number = match input.is_positive() {
        true => Number::U32(input as u32),    #1
        false => Number::I32(input),          #2
    };
    number
}
 
 
fn main() {
    let my_vec = vec![get_number(-800), get_number(8)];
 
    for item in my_vec {
        match item {
            Number::U32(number) => println!("A u32 with the value {number}"),
            Number::I32(number) => println!("An i32 with the value {number}"),
        }
    }
}

A `Vec` needs one item type. Here that type is `Number`: each item is either `U32(u32)` or `I32(i32)`. Matching each item reveals which kind of number it carries. section 4.1.4

A variant with no associated data can also be cast to an integer. Such variants receive numbers starting at 0 by default. You can assign a number with `=`, and an unnumbered variant after it receives the next number. section 4.1.3

An `impl` block can give an enum methods. A method taking `&self` can check the current variant, so callers can write something like `my_mood.check()`. To print an enum with `{:?}`, add `#[derive(Debug)]` above its declaration. section 4.1.5

How Learn Rust in a Month of Lunches covers it

How deep it goes
Works through declaration, matching, associated data, integer casting, and methods using small examples.
Examples
Uses climate choices, sun-or-stars states, signed and unsigned numbers in a Vec, and a mood-checking method.
What it assumes
Builds on basic Rust types, structs, and Vec collections while introducing enum declaration syntax directly.
What you can do after
Build it from scratch: declare variants, attach data, match on choices, and store different payloads under one enum type.
How it connects
Connects enums to structs, pattern matching, Vec collections, methods, and Debug printing.

Also explained in

Compare how 23 books explain enum →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Learn Rust in a Month of Lunches. The section links point to the parts of the book it draws on.