Rust Enums
Defining types with multiple possible variants
🎯 What are Enums?
Enums define types with multiple possible variants, each potentially holding different data. They're perfect for representing states, options, and choices in your programs safely.
enum Direction {
North,
South,
East,
West,
}
Enum Features
Simple Variants
Basic enum variants
enum Status {
Active,
Inactive,
}
Data Variants
Variants that hold data
enum Message {
Text(String),
Number(i32),
}
Methods
Functions on enums
impl Status {
fn is_active(&self) {}
}
Option & Result
Built-in useful enums
Option
Result
🔹 Basic Enums
Simple enums with named variants:
enum TrafficLight {
Red,
Yellow,
Green,
}
fn main() {
let light = TrafficLight::Red;
match light {
TrafficLight::Red => println!("Stop!"),
TrafficLight::Yellow => println!("Caution!"),
TrafficLight::Green => println!("Go!"),
}
// Using if let
if let TrafficLight::Red = light {
println!("The light is red");
}
}
Output:
Stop!
The light is red
The light is red
🔹 Enums with Data
Enum variants can hold different types of data:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
impl Message {
fn process(&self) {
match self {
Message::Quit => println!("Quitting..."),
Message::Move { x, y } => println!("Moving to ({}, {})", x, y),
Message::Write(text) => println!("Writing: {}", text),
Message::ChangeColor(r, g, b) => println!("Changing color to RGB({}, {}, {})", r, g, b),
}
}
}
fn main() {
let messages = vec![
Message::Write(String::from("Hello")),
Message::Move { x: 10, y: 20 },
Message::ChangeColor(255, 0, 0),
Message::Quit,
];
for message in messages {
message.process();
}
}
Output:
Writing: Hello
Moving to (10, 20)
Changing color to RGB(255, 0, 0)
Quitting...
Moving to (10, 20)
Changing color to RGB(255, 0, 0)
Quitting...
🔹 Option Enum
Rust's built-in Option enum for handling null values safely:
fn find_word(text: &str, word: &str) -> Option {
text.find(word)
}
fn main() {
let sentence = "Hello, world!";
match find_word(sentence, "world") {
Some(index) => println!("Found 'world' at index {}", index),
None => println!("'world' not found"),
}
match find_word(sentence, "rust") {
Some(index) => println!("Found 'rust' at index {}", index),
None => println!("'rust' not found"),
}
// Using unwrap_or for default values
let index = find_word(sentence, "hello").unwrap_or(0);
println!("Index with default: {}", index);
}
Output:
Found 'world' at index 7
'rust' not found
Index with default: 0
'rust' not found
Index with default: 0
🔹 Result Enum
Handle operations that might fail with Result:
fn divide(a: f64, b: f64) -> Result {
if b == 0.0 {
Err(String::from("Cannot divide by zero"))
} else {
Ok(a / b)
}
}
fn main() {
let results = vec![
divide(10.0, 2.0),
divide(10.0, 0.0),
divide(15.0, 3.0),
];
for result in results {
match result {
Ok(value) => println!("Result: {}", value),
Err(error) => println!("Error: {}", error),
}
}
// Using unwrap_or for error handling
let safe_result = divide(20.0, 0.0).unwrap_or(-1.0);
println!("Safe result: {}", safe_result);
}
Output:
Result: 5
Error: Cannot divide by zero
Result: 5
Safe result: -1
Error: Cannot divide by zero
Result: 5
Safe result: -1