enum / Variant Definitions
An enum (enumeration) in Rust is a type that can have multiple variants. Each variant can optionally hold data, and comes in three forms: tuple variants, struct variants, and unit variants (no data).
Syntax
// Unit variants — no data attached.
enum Direction {
North,
South,
East,
West,
}
// Tuple variants — hold data positionally.
enum Shape {
Circle(f64), // radius
Rectangle(f64, f64), // width, height
}
// Struct variants — hold data with named fields.
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(u8, u8, u8),
}
// Usage examples.
let dir = Direction::North;
let s = Shape::Circle(3.0);
let msg = Message::Move { x: 10, y: 20 };
Variant Types
| Type | Syntax | Description |
|---|---|---|
| Unit variant | Foo, | A variant that holds no data. |
| Tuple variant | Foo(T1, T2), | A variant that holds data in tuple form. |
| Struct variant | Foo { x: T1, y: T2 }, | A variant that holds data with named fields. |
| Option<T> | Some(T) / None | A standard library enum representing a value that may or may not be present. |
| Result<T, E> | Ok(T) / Err(E) | A standard library enum representing success or failure. |
Sample Code
#[derive(Debug)]
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
#[derive(Debug)]
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
#[derive(Debug)]
enum Event {
KeyPress(char),
MouseMove { x: i32, y: i32 },
Click { button: u8, x: i32, y: i32 },
Resize(u32, u32),
Quit,
}
impl Coin {
// Returns the value in cents for each variant.
fn value_in_cents(&self) -> u32 {
match self {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
}
fn process_event(event: &Event) {
match event {
Event::KeyPress(c) => println!("Key press: {}", c),
Event::MouseMove { x, y } => println!("Mouse move: ({}, {})", x, y),
Event::Click { button, x, y } => {
println!("Click: button {} at ({}, {})", button, x, y)
}
Event::Resize(w, h) => println!("Resize: {}x{}", w, h),
Event::Quit => println!("Quit"),
}
}
fn main() {
// Unit variant.
let coin = Coin::Quarter;
println!("{:?} = {} cents", coin, coin.value_in_cents());
// Tuple variants.
let home = IpAddr::V4(192, 168, 1, 1);
let loopback = IpAddr::V6(String::from("::1"));
println!("{:?}", home);
println!("{:?}", loopback);
// Using various variants.
let events = vec![
Event::KeyPress('a'),
Event::MouseMove { x: 100, y: 200 },
Event::Click { button: 1, x: 50, y: 75 },
Event::Resize(1920, 1080),
Event::Quit,
];
for event in &events {
process_event(event);
}
}
Notes
Rust's enum is more powerful than enumerations in most other languages — each variant can hold a different type and number of values. This is equivalent to a tagged union (discriminated union) in C.
Enum variants belong to the same namespace as the enum type, so you can write use Direction::*; to refer to variants as just North instead of Direction::North.
For adding methods to an enum and pattern matching with match, see impl enum / Pattern Matching with match.
If you find any errors or copyright issues, please contact us.