Enums
Enums define a type that is one of several variants. Variants can hold data, making enums ideal for state machines and error models.
Busca en todas las páginas de la documentación
Enums define a type that is one of several variants. Variants can hold data, making enums ideal for state machines and error models.
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
fn handle(msg: Message) {
match msg {
Message::Quit => println!("quit"),
Message::Move { x, y } => println!("move {x},{y}"),
Message::Write(text) => println!("{text}"),
}
}
fn main() {
handle(Message::Write("hi".into()));
}When to reach for this: Modeling mutually exclusive states, errors, commands, and AST nodes.
enum Traffic {
Red,
Yellow,
Green,
}
impl Traffic {
fn next(self) -> Self {
match self {
Traffic::Red => Traffic::Green,
Traffic::Green => Traffic::Yellow,
Traffic::Yellow => Traffic::Red,
}
}
}
fn main() {
let t = Traffic::Red.next();
println!("{:?}", std::mem::discriminant(&t));
}What this demonstrates:
implself in next for state transition APImatch for exhaustive handlingenum E {
Unit,
Tuple(i32, String),
Struct { id: u64 },
}Rust optimizes niche enums (e.g. Option<&T> same size as &T). Not all enums are same size as largest variant due to optimizations.
Option and Resultenum Option<T> { None, Some(T) }
enum Result<T, E> { Ok(T), Err(E) }See dedicated page for idiomatic use.
match - New variant breaks downstream. Fix: Treat as API semver event; use #[non_exhaustive] for extensibility.Large(Box<Data>).enum Flag { Yes, No } worse than bool unless more states coming. Fix: Use bool until variants multiply.Eq on float payload - Not available. Fix: Use integer representation or avoid Eq.| Alternative | Use When | Don't Use When |
|---|---|---|
Struct + bool flag | Two states only | Many transitions or typed payloads |
| Trait objects | Open set of types | Closed set - enum is faster |
| Integer codes | FFI/C interop | Safe Rust domain modeling |
bitflags crate | Many boolean flags packed | Semantic variants matter |
Yes. Each variant defines its own payload shape.
At least the largest variant; niche optimization may shrink some (e.g. Option).
Yes with impl Trait for MyEnum.
External crates cannot match exhaustively - forward-compatible enum evolution.
Enum: closed known set. Trait: extensible implementations across crates.
Enums cannot be generic per variant, but enum itself can be enum E<T> { Some(T), None } style - use Option.
Option<NonNull<T>> and similar use niche values for None.
#[repr(C)] for FFI layout control - see Unsafe/FFI section.
PascalCase for variants, SCREAMING_SNAKE for enum name is not used - enum is PascalCase too.
Add variant -> compiler lists all match sites to update - feature not bug.
match depth#[derive(...)]Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Revisado por Chris St. John·Última actualización: 16 jul 2026