· Phạm Thành Nam · Ngôn ngữ Rust · 4 phút đọc

30 Ngày học Rust - Day 3: Luồng điều khiển (Control Flow) và sức mạnh của Match

Day 3: Điều hướng luồng chương trình Rust không chỉ bằng 'if else' truyền thống mà còn bằng sức mạnh của vòng lặp vô tận 'loop' và 'match' biểu thức.

Day 3: Điều hướng luồng chương trình Rust không chỉ bằng 'if else' truyền thống mà còn bằng sức mạnh của vòng lặp vô tận 'loop' và 'match' biểu thức.

Lập trình không có ngã rẽ thì chỉ là máy tính cầm tay

Bất cứ ứng dụng nào, từ con bot Discord cơ bản đến thuật toán tên lửa SpaceX, cũng đều cần phải đưa ra quyết định. Nếu A đúng thì thực thi việc B. Trong Rust, logic điều khiển nhánh (Control flow) được hiện thực hóa bằng ba thứ chính: if, vòng lặp (loop, while, for), và điểm sáng rực rỡ nhất: match.

1. Mọi thứ đều là Biểu thức (Expressions)

Bí mật sức mạnh lớn nhất của Rust so với các ngôn ngữ cũ kỹ là: Hầu như mọi thứ trong Rust đều trả về một giá trị, vì chúng là Expression.

Hãy xem cách if cấu tạo nên một gán biến siêu gọn:

fn main() {
    let condition = true;
    
    // Nếu là JS bạn sẽ phải xài toán tử ba ngôi (condition ? 6 : 5)
    // Ở Rust, khối `if` có thể bưng thẳng gán vào hàm:
    let number = if condition { 6 } else { 5 };

    println!("Giá trị là: {}", number);
}

Lưu ý: Bạn không được nhét dấu chấm phẩy ; vào đuôi số 6 hoặc 5 ở trong khối ngoặc nhọn {}. Nếu bạn để ;, Rust coi đó là kết thúc câu lệnh, nó sẽ không return ra số 6 để nhét vào cụm number nữa.

2. Vòng lặp: loop, while, for

Rust cung cấp 3 cỗ máy vòng lặp cho các mục đích riêng biệt:

  • loop: Lặp vô tận. Nó lặp chết bỏ cho đến khi bạn hét lên lệnh break. Thường dùng ở các trình giả lập game (Game loop lắng nghe màn hình phím bấm 60fps) hoặc server chạy 24/7.
  • while: Lặp với điều kiện (y hệt C++).
  • for: Vua của mọi vòng lặp. 90% thời gian bạn sẽ dùng cái này. Nó duyệt qua từng phần tử một cách xuất sắc mà không bị dính lỗi Out of Bounds (Bắn khỏi mảng).

Ví dụ lặp xịn xò của for:

for number in (1..4).rev() { // rev() là reverse đảo ngược đếm lùi
    println!("{}...", number);
}
println!("PHÓNG!"); // In ra: 3... 2... 1... PHÓNG!

3. “Match” - Cây đũa phép định hình RUST

Trong lúc chờ đến Day 7 để học sâu về Enum, bạn phải biết đến match - phiên bản tiến hóa lên GOD mode của switch/case bên C/JS.

Trình biên dịch Rust BẮT BUỘC bạn phải lo liệu TẤT CẢ TÌNH HUỐNG (Exhaustive) nếu dùng Match. Lỗ hổng quên xử lý rác sẽ không đội sổ diễn ra:

let lua_chon = 2;

match lua_chon {
    1 => println!("Bạn chọn Vàng"),
    2 => println!("Bạn chọn Bạc"),
    // Quên điền các số khác? Rust không cho Compile đâu!
    _ => println!("Bạn chọn Nhôm"), // Dấu gạch dưới '_' hứng tất cả trường hợp còn lại
}

Sức mạnh của match khủng khiếp ở chỗ, nó không những so khớp số nguyên, nó còn có thể so khớp Enum, bắt trọn Data bên trong ống rỗng, bẻ khóa Pattern… giúp phân luồng lỗi (Error Handle) hoàn mỹ — thứ sẽ được giới thiệu ở Ngày 10.

Câu hỏi thường gặp (FAQ)

Rust có toán tử điều kiện (Ternary Operator) kiểu ? : không?

Không. Với tư duy làm cho ngôn ngữ minh bạch và ít lộn xộn, nhóm phát triển Rust quyết định không chèn toán tử ? : vì dùng thẳng khối lệnh if else (như ví dụ 1 ở trên) vừa làm được chuyện ấy lại vừa rõ ràng, không đẻ thêm cú pháp thừa thãi.

Việc sử dụng _ (Wildcard) trong match có gì lưu ý?

_ ôm trọn “mọi thứ còn lại” (the rest), bạn phải vứt cành này xuống cuối cùng của cấu trúc match. Tuy nhiên, về mặt thiết kế an toàn của các hệ thống ngặt nghèo (Critical system), các DEV kỳ cựu ở Rust khuyên bạn Hạn chế dùng _. Tại sao? Vì nếu tương lai bạn cập nhật thêm lựa chọn 3 => "Đồng", nhưng bạn lỡ quên sửa logic. Nhờ không dùng _, Rust sẽ gào lên báo lỗi giúp bạn nhớ. Nếu có _, code vẫn pass qua nhẹ nhàng và ẩn đi một bug khủng bố chờ bom nổ.


Sẵn sàng cho Ngày 4? Biến? Ok. Điều khiển nhánh? Ok. Bạn chỉ còn cách chức danh Rustacean một cánh cửa duy nhất. Bài viết ngày mai sẽ dạy bạn bức tường khó nhằn và đặc trưng nhất của Rust: [Day 4: Ownership - Kẻ thao túng bộ nhớ].

Chuỗi bài viết

30 Ngày Trở Thành Rustacean Tinh Hoa

Phần 3 / 30

30 bài viết
  1. Phần 1 30 Ngày học Rust - Day 1: Lời chào thế giới và Vũ khí Cargo
  2. Phần 2 30 Ngày học Rust - Day 2: Biến, Bất biến (Mutability) và Shadowing
  3. 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
  4. Phần 4 30 Ngày học Rust - Day 4: Ownership - Khái niệm định hình cỗ thần khí Rust
  5. Phần 5 30 Ngày học Rust - Day 5: Khóa học nhặt đồ chung với References & Borrowing
  6. Phần 6 30 Ngày học Rust - Day 6: Đắp nặn dự án với Structs và Methods
  7. Phần 7 30 Ngày học Rust - Day 7: Quyền năng vô song của Enums và Pattern Matching
  8. Phần 8 30 Ngày học Rust - Day 8: Quản lý dự án với Packages, Crates và Modules
  9. Phần 9 30 Ngày học Rust - Day 9: Các bộ sưu tập chung (Vectors, Strings, Hash Maps)
  10. Phần 10 30 Ngày học Rust - Day 10: Trị dứt điểm Ác mộng Lỗi (Error Handling)
  11. Phần 11 30 Ngày học Rust - Day 11: Generics - Ma thuật Đa hình kiểu dữ liệu
  12. 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
  13. Phần 13 30 Ngày học Rust - Day 13: Vượt qua Boss cuối 'Lifetimes' - Sinh Mệnh Biến
  14. 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
  15. Phần 15 30 Ngày học Rust - Day 15: Thực chiến Build Command Line App (CLI) đầu đời
  16. Phần 16 30 Ngày học Rust - Day 16: Functional Magic chốn trần gian (Closures & Iterators)
  17. Phần 17 30 Ngày học Rust - Day 17: Quyền năng của Smart Pointers
  18. 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
  19. 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
  20. Phần 20 30 Ngày học Rust - Day 20: Mổ xẻ nghệ thuật Advanced Pattern Matching
  21. Phần 21 30 Ngày học Rust - Day 21: Sức mạnh tối thượng của Advanced Traits
  22. Phần 22 30 Ngày học Rust - Day 22: Về Phe Bóng Tối với Unsafe Rust
  23. Phần 23 30 Ngày học Rust - Day 23: Quyền năng của Đấng Tạo Hóa (Declarative Macros)
  24. Phần 24 30 Ngày học Rust - Day 24: Siêu Năng Lực Procedural Macros (Macro Thủ Tục)
  25. 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)
  26. 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)
  27. 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)
  28. 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)
  29. 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
  30. 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

Bình luận

Quay lại Blog

Bài viết liên quan

Xem tất cả bài viết »