Lesson 3 — Working with Structs, Enums, and Pattern Matching
🎯 Learning Objectives
- Nắm vững cách định nghĩa struct và enum trong Rust.
- Hiểu cơ chế pattern matching với
match,if let,while let. - Biết áp dụng pattern để destructure dữ liệu, quản lý state và xử lý
Result/Option.
🔑 Key Concepts & Glossary
- Struct gom nhiều field thành một kiểu dữ liệu.
- Có 3 dạng: Named struct, Tuple struct, Unit struct.
- Enum cho phép một giá trị là một trong nhiều biến thể (variant).
- Mỗi variant có thể chứa dữ liệu khác nhau.
matchlà exhaustive (bắt buộc cover hết trường hợp).if let/while letkhi chỉ quan tâm một pattern cụ thể.- Có thể destructure enum, struct, tuple, slice trực tiếp trong pattern.
Các thuật ngữ quan trọng:
- Destructuring: Bóc tách giá trị trong pattern.
- Wildcard (
_): Bỏ qua giá trị không quan tâm. ..: Bỏ qua các field còn lại.- Exhaustiveness check: Compiler buộc
matchphải xử lý hết các case có thể.
💻 Example Implementation
Cargo.toml
[package]
name = "lesson03_struct_enum_match"
version = "0.1.0"
edition = "2024"
src/main.rs
#[derive(Debug)] struct Credential { username: String, password: String, } enum AuthResult { Success { user: String }, Failure(String), Locked, } fn authenticate(cred: Credential) -> AuthResult { if cred.username == "admin" && cred.password == "1234" { AuthResult::Success { user: cred.username } } else if cred.username == "root" { AuthResult::Locked } else { AuthResult::Failure(format!("Invalid credentials for {}", cred.username)) } } fn main() { let creds = vec![ Credential { username: "admin".into(), password: "1234".into() }, Credential { username: "alice".into(), password: "wrong".into() }, Credential { username: "root".into(), password: "toor".into() }, ]; for cred in creds { match authenticate(cred) { AuthResult::Success { user } => println!("✅ Welcome, {user}!"), AuthResult::Failure(msg) => println!("❌ {msg}"), AuthResult::Locked => println!("🚫 Account is locked"), } } }
🛠️ Hands-on Exercises
-
Struct Exercise Tạo struct
Packet { src: String, dst: String, payload: Vec<u8> }→ Viết hàm in rasrc -> dst (size = n bytes). -
Enum Exercise Định nghĩa enum
LogLevel { Info, Warning, Error(String) }→ Viết hàmlog(level: LogLevel)in log phù hợp. -
Pattern Matching Challenge Tạo struct
Packet { src: String, dst: String, payload: Vec<u8>, port: String }. → Viết hàmparse_portvà dùng let-else/if-let để xử lý.
🐞 Common Pitfalls & Debugging Tips
- Quên cover hết branch trong
match→ compiler báo lỗi. - Lạm dụng
_trongmatch→ có thể bỏ sót bug logic. - Dùng enum mà không derive trait (Debug, Clone, Eq, …) → khó debug/log.
🔄 Migration Notes (Rust 2024+)
- Không có breaking change cho struct/enum.
- Rust 2024 cải thiện ergonomic: destructuring trong
let-elsevà closure tiện hơn. if let/while letpattern binding ngày càng phổ biến, thay thế match dài dòng.
❓ Q&A — Common Questions
Q1. Khi nào dùng struct, khi nào dùng enum?
- Struct: gom nhiều field cố định.
- Enum: biểu diễn nhiều trạng thái khác nhau, mỗi trạng thái có thể chứa dữ liệu riêng.
Q2. Khi nào dùng match, khi nào if let?
match: khi cần cover hết các trường hợp.if let: khi chỉ quan tâm một case.
Q3. _ và .. trong pattern nghĩa là gì?
_: bỏ qua giá trị không quan tâm...: bỏ qua các field còn lại (struct/tuple/slice).
📚 References
- The Rust Book — Enums and Pattern Matching
- Black Hat Rust (case study cho tool offensive & security).
🌿 Wisdom Note
Hữu vô tương sinh, nan dị tương thành. (Being and non-being give birth to each other; difficulty and ease complete each other.)
Struct và enum cũng vậy: struct cho hình hài, enum cho trạng thái. Kết hợp với pattern matching, bạn có thể diễn đạt logic an toàn và rõ ràng như chính Đạo.