title: Enums
An enum defines a type that can be one of several possible variants. Unlike enums in most languages, Rust enum variants can each hold their own data.
Basic enum
enum Direction {
North,
South,
East,
West,
}
let dir = Direction::North;Variants with data
Each variant can hold different types and amounts of data:
enum Message {
Quit, // no data
Move { x: i32, y: i32 }, // named fields
Write(String), // single value
ChangeColor(u8, u8, u8), // multiple values
}This is a key difference from most languages — a single enum type can represent several structurally different things.
Using match with enums
Enums and match go hand in hand. Match lets you handle each variant and extract its data:
fn handle(msg: Message) {
match msg {
Message::Quit => println!("quit"),
Message::Move { x, y } => println!("move to {x}, {y}"),
Message::Write(text) => println!("write: {text}"),
Message::ChangeColor(r, g, b) => println!("color: {r}, {g}, {b}"),
}
}Methods on enums
Just like structs, enums can have methods:
impl Message {
fn is_quit(&self) -> bool {
matches!(self, Message::Quit)
}
}Enums vs structs
Use a struct when you always have all fields present. Use an enum when a value can be one of several distinct shapes. For example, a network packet could be a Connect, Data, or Disconnect — that’s a natural enum because you’ll never have all three at once.
Option and Result
Rust’s two most important enums are built into the standard library:
Option<T>— a value that may or may not exist (see [[option]])Result<T, E>— a value that is either a success or an error (see [[result]])
Both follow the same pattern: an enum whose variants carry data, used with match to handle each case.