rust/src/doc/trpl/enums.md
2015-05-12 20:21:21 -04:00

2.0 KiB
Raw Blame History

% Enums

An enum in Rust is a type that represents data that could be one of several possible variants:

enum Message {
    Quit,
    ChangeColor(i32, i32, i32),
    Move { x: i32, y: i32 },
    Write(String),
}

Each variant can optionally have data associated with it. The syntax for defining variants resembles the syntaxes used to define structs: you can have variants with no data (like unit-like structs), variants with named data, and variants with unnamed data (like tuple structs). Unlike separate struct definitions, however, an enum is a single type. A value of the enum can match any of the variants. For this reason, an enum is sometimes called a sum type: the set of possible values of the enum is the sum of the sets of possible values for each variant.

We use the :: syntax to use the name of each variant: theyre scoped by the name of the enum itself. This allows both of these to work:

# enum Message {
#     Move { x: i32, y: i32 },
# }
let x: Message = Message::Move { x: 3, y: 4 };

enum BoardGameTurn {
    Move { squares: i32 },
    Pass,
}

let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };

Both variants are named Move, but since theyre scoped to the name of the enum, they can both be used without conflict.

A value of an enum type contains information about which variant it is, in addition to any data associated with that variant. This is sometimes referred to as a tagged union, since the data includes a tag indicating what type it is. The compiler uses this information to enforce that youre accessing the data in the enum safely. For instance, you cant simply try to destructure a value as if it were one of the possible variants:

fn process_color_change(msg: Message) {
    let Message::ChangeColor(r, g, b) = msg; // compile-time error
}

Well see how to safely get data out of enums when we learn about the match and if let statements in the next few chapters.