Basic Enums
Enums in Rust are way more powerful than in C or Java. Each variant can hold different types and amounts of data, not just a number. Think of an enum as a type that can be one of several things โ and each thing can carry its own payload.
enum Direction {
North,
South,
East,
West,
}
fn main() {
let dir = Direction::North;
}
Try it Yourself ->
Enums with Data
Here's where it gets interesting. Each variant can store different kinds of data. An IP address can be either V4 or V6, and each format uses different data. Rust lets you express that naturally.
enum IpAddr {
V4(u8, u8, u8, u8),
V6(String),
}
fn main() {
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));
}
Try it Yourself ->
The Option Enum
Rust doesn't have null. Instead, it has Option<T>, which is an enum with two variants: Some(value) or None. This forces you to explicitly handle the case where a value might be missing, which eliminates a huge class of runtime errors.
fn main() {
let some_number: Option<i32> = Some(42);
let no_number: Option<i32> = None;
println!("some_number: {:?}", some_number);
println!("no_number: {:?}", no_number);
}
Try it Yourself ->
Enums with Methods
You can attach methods to enums using impl blocks, just like structs. This lets you define behavior that varies based on which variant you're working with.
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
impl Coin {
fn value_in_cents(&self) -> u32 {
match self {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
}
fn main() {
let coin = Coin::Dime;
println!("Value: {} cents", coin.value_in_cents());
}
Try it Yourself ->