Rust Enums
An enum (short for enumeration) defines a type that can be one of a fixed set of possibilities. If a struct is for “this thing has all of these fields,” an enum is for “this thing is exactly one of these options.”
Defining and using an enum
Section titled “Defining and using an enum”enum Direction { North, South, East, West,}
fn main() { let heading = Direction::North;
match heading { Direction::North => println!("Heading north"), Direction::South => println!("Heading south"), Direction::East => println!("Heading east"), Direction::West => println!("Heading west"), }}Output:
Heading northNotice match here doesn’t need a _ catch-all — because every possible Direction is listed, Rust can already tell the match is complete.
Enums can hold data
Section titled “Enums can hold data”This is where Rust’s enums go further than a typical enum in other languages: each variant can carry its own data:
enum Shape { Circle(f64), // radius Rectangle(f64, f64), // width, height}
fn area(shape: &Shape) -> f64 { match shape { Shape::Circle(radius) => 3.14159 * radius * radius, Shape::Rectangle(width, height) => width * height, }}
fn main() { let circle = Shape::Circle(3.0); let rectangle = Shape::Rectangle(4.0, 5.0);
println!("{:.2}", area(&circle)); println!("{:.2}", area(&rectangle));}Output:
28.2720.00Shape::Circle carries one f64 (the radius); Shape::Rectangle carries two. match pulls that data straight out for you in each arm — no separate step needed to “unwrap” it.
Option: an enum you’ve already been using
Section titled “Option: an enum you’ve already been using”The Option type you’ll meet properly on its own page is just an enum defined in the standard library:
enum Option<T> { Some(T), None,}Once enums click, Option stops looking like special syntax — it’s a completely ordinary enum with two variants, one of which happens to carry a value.
Why not just use a struct with a “type” field?
Section titled “Why not just use a struct with a “type” field?”You could imagine faking this with a struct and a string field like "circle" or "rectangle" — but then nothing stops you from typing "circl" by mistake, and you’d need to manually check which fields are actually relevant for each type. An enum makes invalid combinations impossible to write in the first place, and the compiler forces you to handle every variant.
- An enum defines a type as one of several named variants:
enum Direction { North, South, ... }. - Variants can carry their own data, and different variants can carry different data.
matchnaturally destructures enum data and requires every variant to be handled.Option(andResult, covered next) are just enums from the standard library — nothing magic about them.
Quick check
Section titled “Quick check”Quick check
1. What can each variant of a Rust enum do, unlike a typical enum in other languages?
2. Why doesn't the Direction match example need a catch-all _ arm?
3. What is Option<T> actually implemented as in the standard library?
Score: 0 / 3