🎲 Enums: Một Trong Nhiều Khả Năng
🎯 Mục Tiêu Bài Học
Sau khi hoàn thành bài học này, bạn sẽ:
- ✅ Hiểu được enum là gì và khi nào dùng
- ✅ Định nghĩa enums với các variants
- ✅ Sử dụng enum variants với data
- ✅ Pattern matching với
match - ✅ Hiểu preview về
OptionvàResult - ✅ Áp dụng enums trong code thực tế
🤔 Enum Là Gì?
Ẩn Dụ Cuộc Sống: Trạng Thái Đơn Hàng
Enum giống như trạng thái đơn hàng:
📦 Đơn Hàng:
- Chỉ có một trạng thái tại một thời điểm
- Có thể là: Đang chờ, Đang giao, Đã giao, Đã hủy
- Không thể vừa "Đang giao" vừa "Đã hủy"
🎲 Enum Trong Rust:
- Định nghĩa một tập hợp các khả năng
- Giá trị chỉ có thể là một variant
- Type-safe: Compiler đảm bảo bạn xử lý tất cả cases
Tại Sao Cần Enums?
Không dùng enum (dễ lỗi):
const PENDING: i32 = 0;
const SHIPPING: i32 = 1;
const DELIVERED: i32 = 2;
const CANCELLED: i32 = 3;
fn main() {
let status = 1;
// ❌ Dễ nhầm lẫn, không type-safe
if status == SHIPPING {
println!("Đang giao hàng");
}
// ❌ Có thể dùng số bất kỳ
let invalid_status = 99; // Lỗi logic!
}
Dùng enum (an toàn):
enum OrderStatus {
Pending,
Shipping,
Delivered,
Cancelled,
}
fn main() {
let status = OrderStatus::Shipping;
// ✅ Type-safe, compiler kiểm tra
match status {
OrderStatus::Pending => println!("Đang chờ"),
OrderStatus::Shipping => println!("Đang giao"),
OrderStatus::Delivered => println!("Đã giao"),
OrderStatus::Cancelled => println!("Đã hủy"),
}
}
📦 Định Nghĩa Enums
Cú Pháp Cơ Bản
enum Direction {
North,
South,
East,
West,
}
fn main() {
let dir = Direction::North;
match dir {
Direction::North => println!("Đi Bắc"),
Direction::South => println!("Đi Nam"),
Direction::East => println!("Đi Đông"),
Direction::West => println!("Đi Tây"),
}
}
Giải thích:
enum Direction→ Định nghĩa enumNorth,South, ... → Các variantsDirection::North→ Tạo giá trị
Enum Với Data
Variants có thể chứa dữ liệu:
enum Message {
Quit, // Không có data
Move { x: i32, y: i32 }, // Struct-like
Write(String), // Tuple-like
ChangeColor(i32, i32, i32), // Multiple values
}
fn main() {
let msg1 = Message::Quit;
let msg2 = Message::Move { x: 10, y: 20 };
let msg3 = Message::Write(String::from("Hello"));
let msg4 = Message::ChangeColor(255, 0, 0);
process_message(msg3);
}
fn process_message(msg: Message) {
match msg {
Message::Quit => {
println!("Thoát chương trình");
}
Message::Move { x, y } => {
println!("Di chuyển đến ({}, {})", x, y);
}
Message::Write(text) => {
println!("Viết: {}", text);
}
Message::ChangeColor(r, g, b) => {
println!("Đổi màu RGB({}, {}, {})", r, g, b);
}
}
}
Đầu ra:
Viết: Hello
🎯 Pattern Matching
Match Expression
enum TrafficLight {
Red,
Yellow,
Green,
}
fn main() {
let light = TrafficLight::Red;
let action = match light {
TrafficLight::Red => "Dừng",
TrafficLight::Yellow => "Chuẩn bị",
TrafficLight::Green => "Đi",
};
println!("{}", action);
}
Đặc điểm:
matchphải exhaustive (xử lý tất cả cases)- Mỗi arm trả về cùng kiểu
- Compiler kiểm tra đầy đủ