Rust Enums: Data-Carrying Variants
#[derive(Debug)]
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
#[derive(Debug)]
enum Event {
KeyPress(char),
MouseClick { x: f64, y: f64 },
Resize(u32, u32),
Quit,
}
impl Event {
fn describe(&self) -> String {
match self {
Event::KeyPress(c) => format!("Key: {}", c),
Event::MouseClick { x, y } => format!("Click at ({:.1}, {:.1})", x, y),
Event::Resize(w, h) => format!("Resize to {}x{}", w, h),
Event::Quit => String::from("Quit"),
}
}
}
fn main() {
let events = vec![
Event::KeyPress('a'),
Event::MouseClick { x: 100.5, y: 200.0 },
Event::Resize(1920, 1080),
Event::Quit,
];
for e in &events { println!("{}", e.describe()); }
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
println!("{:?} {:?}", home, loopback);
}Enums as State Machines
#[derive(Debug, PartialEq)]
enum OrderStatus {
Pending,
Processing { start: u64 },
Shipped { tracking: String },
Delivered,
Cancelled(String),
}
impl OrderStatus {
fn can_cancel(&self) -> bool {
matches!(self, OrderStatus::Pending | OrderStatus::Processing { .. })
}
fn is_final(&self) -> bool {
matches!(self, OrderStatus::Delivered | OrderStatus::Cancelled(_))
}
}
fn main() {
let mut order = OrderStatus::Pending;
println!("{:?} can_cancel={}", order, order.can_cancel());
order = OrderStatus::Processing { start: 1234567890 };
println!("{:?} can_cancel={}", order, order.can_cancel());
order = OrderStatus::Shipped { tracking: "1Z999AA1".to_string() };
println!("{:?} final={}", order, order.is_final());
order = OrderStatus::Delivered;
println!("{:?} final={}", order, order.is_final());
}🎯 Practice
- Create a Shape enum: Circle(f64), Rectangle(f64,f64), Triangle(f64,f64,f64). Implement area() and perimeter()
- Create a Command enum for a simple shell: Cd(String), Ls, Echo(String), Exit. Implement execute()
- Use the matches! macro to check if an enum value is one of several variants
🎉 Key Takeaways
- Enum variants can be unit, tuple-style, or struct-style with named fields
- match ensures exhaustive handling of all variants
- Enums with impl are perfect for state machines and type-safe dispatch
- matches!(val, Pattern) is a concise way to check an enum variant