30 Ngày học Rust - Day 7: Quyền năng vô song của Enums và Pattern Matching
Day 7: Trãi nghiệm tính năng Enum 'khác người' của Rust - Nơi Enum không chỉ là các danh sách nhãn dán, mà là những vật tải dữ liệu thần thánh kết hợp cùng lệnh match.

Khi Enum lột xác thành quái vật
Trong đa số ngôn ngữ lập trình khác (Java, C#, JS Typescript), Enum (Liệt kê) chỉ đơn thuần là gán một cái tên cho một con số. Ví dụ: enum Direction { N, S, E, W }. Nó khá vô hại và tĩnh.
Trong Rust, Enum là một thứ hoàn toàn khác biệt ở đẳng cấp vũ trụ. Nó không chỉ là các “Lựa chọn định danh” (Variants), nó còn có quyền nhồi trực tiếp một Cấu trúc dữ liệu (Data) chà bá vào ngay sau biến thể của chính nó.
1. Mở ra giới hạn mới của Enums
Chúng ta xây ứng dụng phân tích Giao thức Internet. IP có IPv4 và IPv6. Trong Cấu trúc cũ, bạn phải lập 1 Struct chung bao gồm ID Enum và kèm theo mốc chứa chuỗi. Trông siêu ngớ ngẩn.
Còn đây là cách Rust làm:
enum IpAddr {
V4(u8, u8, u8, u8), // Chứa 4 số cục bộ (Giống Tuple)
V6(String), // V6 chứa 1 cái String bự
}
// Khai báo siêu tự do mà gom chung 1 loại "IpAddr"!
let home = IpAddr::V4(127, 0, 0, 1);
let loopback = IpAddr::V6(String::from("::1"));Chưa hết, một cái Enum thậm chí có thể chứa nguyên cái Struct vô nó! Điều này biến Enum thành chiếc đòn gánh gom tất cả các loại Mảng / Biến / Struct khác nhau vào chung MỘT TYPE. Cực kỳ mạnh khi lập trình Web socket trả về N loại Tin nhắn.
2. Match - Lưới bắt không dính một hạt bụi
Cỗ máy hoàn hảo để “mổ xẻ” cái Enum biến hóa khôn lường trên chính là lệnh match. Match không chỉ xoi xói xem đó là cái gì, nó sẽ Thò tay móc túi móc thẳng data ở trong ra:
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
}
fn process_msg(msg: Message) {
match msg {
Message::Quit => println!("App thoát mất tiêu"),
Message::Move { x, y } => println!("Đi tới {} và {}", x, y),
Message::Write(text) => println!("Bạn gõ chữ: {}", text),
}
}Hãy nhìn vào Move và Write. Bằng phép thuật liên kết Pattern, lệnh in được sử dụng ngay biến x, y hoặc text từ ống nghiệm ruột Enum đưa ra rực rỡ và an toàn.
3. Cú đánh tỉa if let
Nếu bạn dùng match nhưng chỉ nhắm tới đúng 1 trường hợp cụ thể và vứt sọt rác toàn bộ phần dư lại (dùng cành rác _ => ()), thì code sẽ hơi dài. Viết tắt nó với chốt chặn if let:
let config_max = Some(3u8);
// HACK NGẮN GỌN: Chỉ khi config_max bằng Some(max) thì chạy khối lệnh
if let Some(max) = config_max {
println!("Duyệt luôn số Max tại {}", max);
}Lưu ý: Bạn mất đi cái vòng tròn bảo mật Exhaustive (Kiểm tra đủ cành) của match.
Câu hỏi thường gặp (FAQ)
Option<T> được quảng cáo ghê gớm lắm, nó là gì vậy?
Đó là pha cứu thua thế kỉ của Rust. Năm 1965, ngài Tony Hoare thả Null Reference vào lập trình, tạo ra lỗi “NullPointerException” gây thiệt hại ròng một tỷ Dollar tỷ Dollar suốt 50 năm qua. Rust quyết định Không tồn tại Null. Thay vào đó, nó đẻ ra Enum gọi là Option. Trong đó chứa 2 loại vỏ hạt: Some(gia_tri) (Có Data) và None (Null). Bạn BẮT BUỘC phải dùng Lệnh Match để mở cái vỏ đó ra thành 2 cành gạt. Quá trình chia này khiến bạn mãi mãi không quên việc xử lý lỗi lỡ lấy phải Data rác.
Sẵn sàng cho Tuần 2? Xin chúc mừng! Bạn đã tốt nghiệp khóa Core Mầm Non của Rust. Chào đón Ngày tiếp theo cũng thay đổi quy mô, biến File Test thành một Tòa tháp dự án to đùng trong [Day 8: Quản lý Packages, Crates & Modules].
Chuỗi bài viết
30 Ngày Trở Thành Rustacean Tinh Hoa
Phần 7 / 30
- Phần 1 30 Ngày học Rust - Day 1: Lời chào thế giới và Vũ khí Cargo
- Phần 2 30 Ngày học Rust - Day 2: Biến, Bất biến (Mutability) và Shadowing
- Phần 3 30 Ngày học Rust - Day 3: Luồng điều khiển (Control Flow) và sức mạnh của Match
- Phần 4 30 Ngày học Rust - Day 4: Ownership - Khái niệm định hình cỗ thần khí Rust
- Phần 5 30 Ngày học Rust - Day 5: Khóa học nhặt đồ chung với References & Borrowing
- Phần 6 30 Ngày học Rust - Day 6: Đắp nặn dự án với Structs và Methods
- Phần 7 30 Ngày học Rust - Day 7: Quyền năng vô song của Enums và Pattern Matching
- Phần 8 30 Ngày học Rust - Day 8: Quản lý dự án với Packages, Crates và Modules
- Phần 9 30 Ngày học Rust - Day 9: Các bộ sưu tập chung (Vectors, Strings, Hash Maps)
- Phần 10 30 Ngày học Rust - Day 10: Trị dứt điểm Ác mộng Lỗi (Error Handling)
- Phần 11 30 Ngày học Rust - Day 11: Generics - Ma thuật Đa hình kiểu dữ liệu
- Phần 12 30 Ngày học Rust - Day 12: Traits - Kẻ ban phát quyền năng và Lập pháp Hành vi
- Phần 13 30 Ngày học Rust - Day 13: Vượt qua Boss cuối 'Lifetimes' - Sinh Mệnh Biến
- Phần 14 30 Ngày học Rust - Day 14: Tận diệt Bug từ trứng nước bằng Automated Tests
- Phần 15 30 Ngày học Rust - Day 15: Thực chiến Build Command Line App (CLI) đầu đời
- Phần 16 30 Ngày học Rust - Day 16: Functional Magic chốn trần gian (Closures & Iterators)
- Phần 17 30 Ngày học Rust - Day 17: Quyền năng của Smart Pointers
- Phần 18 30 Ngày học Rust - Day 18: Chinh phục Da luồng (Concurrency) - Cú đâm quyết định của Rust
- Phần 19 30 Ngày học Rust - Day 19: Tranh cãi Lập trình hướng đối tượng (OOP) trong Rust
- Phần 20 30 Ngày học Rust - Day 20: Mổ xẻ nghệ thuật Advanced Pattern Matching
- Phần 21 30 Ngày học Rust - Day 21: Sức mạnh tối thượng của Advanced Traits
- Phần 22 30 Ngày học Rust - Day 22: Về Phe Bóng Tối với Unsafe Rust
- Phần 23 30 Ngày học Rust - Day 23: Quyền năng của Đấng Tạo Hóa (Declarative Macros)
- Phần 24 30 Ngày học Rust - Day 24: Siêu Năng Lực Procedural Macros (Macro Thủ Tục)
- Phần 25 30 Ngày học Rust - Day 25: Xây dựng TCP Web Server Đa Luồng (Phần 1: Lõi Socket)
- Phần 26 30 Ngày học Rust - Day 26: Xây dựng TCP Web Server Đa Luồng (Phần 2: Bắn trả File HTML)
- Phần 27 30 Ngày học Rust - Day 27: Xây dựng TCP Web Server Đa Luồng (Phần 3: The Thread Pool)
- Phần 28 30 Ngày học Rust - Day 28: Xây dựng TCP Web Server Đa Luồng (Phần 4: Graceful Shutdown)
- Phần 29 30 Ngày học Rust - Day 29: Lên đỉnh Web Server Thực Chiến với Axum và Tokio
- Phần 30 30 Ngày học Rust - Day 30: Vượt Vọng Vàng - Đúc Kết Hành Trình Rustacean Tinh Hoa