Menu
CoddyTech

Phương thức của enum

Thuộc phần Lập trình hướng đối tượng trong hành trình Rust của Coddy. Bài học 15 trên 61.

Cũng như struct, enum có thể định nghĩa phương thức trong các khối impl. Nhờ vậy, bạn có thể gắn hành vi trực tiếp vào kiểu enum, giúp làm việc với các biến thể khác nhau qua một giao diện thống nhất.

Đây là cách thêm một phương thức vào enum Message từ bài học trước:

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
}

impl Message {
    fn describe(&self) -> String {
        match self {
            Message::Quit => String::from("Quit signal"),
            Message::Move { x, y } => format!("Move to ({}, {})", x, y),
            Message::Write(text) => format!("Message: {}", text),
        }
    }
}

Khối impl Message hoạt động giống hệt như với các struct. Phương thức nhận &self để truy cập vào instance của enum. Bên trong phương thức, bạn dùng match để xác định biến thể nào đang được xử lý và trả về kết quả phù hợp.

Cách gọi phương thức giống nhau bất kể bạn có biến thể nào:

fn main() {
    let m1 = Message::Quit;
    let m2 = Message::Move { x: 10, y: 20 };
    
    println!("{}", m1.describe());  // Tín hiệu Quit
    println!("{}", m2.describe());  // Move đến (10, 20)
}

Mẫu này rất hữu ích vì bên gọi không cần biết mình đang có biến thể nào. Họ chỉ cần gọi phương thức, còn enum tự xử lý phần còn lại. Hành vi thay đổi tùy theo biến thể, nhưng giao diện vẫn nhất quán.

challenge icon

Thử thách

Dễ

Hãy xây dựng một hệ thống đèn giao thông dùng enum cùng các phương thức để mô tả trạng thái tín hiệu hiện tại. Mỗi màu đèn sẽ chứa thông tin về thời gian đèn sáng, còn một phương thức sẽ cung cấp phần mô tả dễ hiểu.

Bạn sẽ tạo hai tệp để sắp xếp code:

  • traffic.rs: Định nghĩa enum công khai TrafficLight với ba biến thể:
    • Red: chứa một giá trị u32 biểu thị số giây cần chờ
    • Yellow: chứa một giá trị u32 biểu thị số giây cần chờ
    • Green: chứa một giá trị u32 biểu thị số giây được đi
    Sau đó, triển khai phương thức status trả về một String mô tả đèn. Dùng match bên trong phương thức để xử lý từng biến thể và đưa thời lượng vào thông báo.
  • main.rs: Đưa module đèn giao thông vào, tạo instance cho từng biến thể đèn, rồi gọi phương thức status trên từng instance để in ra phần mô tả.

Phương thức status cần trả về thông báo theo đúng các định dạng sau:

  • Với Red: Stop for {seconds} seconds
  • Với Yellow: Caution for {seconds} seconds
  • Với Green: Go for {seconds} seconds

Đầu ra cần hiển thị trạng thái của mỗi đèn trên một dòng riêng:

Stop for {seconds} seconds
Caution for {seconds} seconds
Go for {seconds} seconds

Ví dụ, nếu đèn đỏ sáng trong 30 giây, đèn vàng trong 5 giây và đèn xanh trong 25 giây, đầu ra sẽ là:

Stop for 30 seconds
Caution for 5 seconds
Go for 25 seconds

Bạn sẽ nhận ba đầu vào: thời lượng đèn đỏ, thời lượng đèn vàng và thời lượng đèn xanh.

Tự làm thử

mod traffic;

use traffic::TrafficLight;

fn main() {
    // Đọc đầu vào cho thời lượng của các đèn
    let mut red_input = String::new();
    std::io::stdin().read_line(&mut red_input).expect("Failed to read line");
    let red_duration: u32 = red_input.trim().parse().expect("Invalid number");

    let mut yellow_input = String::new();
    std::io::stdin().read_line(&mut yellow_input).expect("Failed to read line");
    let yellow_duration: u32 = yellow_input.trim().parse().expect("Invalid number");

    let mut green_input = String::new();
    std::io::stdin().read_line(&mut green_input).expect("Failed to read line");
    let green_duration: u32 = green_input.trim().parse().expect("Invalid number");

    // TODO: Tạo instance cho từng biến thể TrafficLight với thời lượng đầu vào

    // TODO: Gọi phương thức status trên từng đèn và in ra kết quả
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Lập trình hướng đối tượng

Tự luyện tập: Trình biên dịch Rust online