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.
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 khaiTrafficLightvới ba biến thể:Red: chứa một giá trịu32biểu thị số giây cần chờYellow: chứa một giá trịu32biểu thị số giây cần chờGreen: chứa một giá trịu32biểu thị số giây được đi
statustrả về mộtStringmô tả đèn. Dùngmatchbê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ứcstatustrê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} secondsVí 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 secondsBạ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ả
}
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
1Phương thức và hành vi
Nhập môn khối triển khaiTham số selfPhương thức có thể thay đổiHàm liên kếtNhiều khối triển khaiNối chuỗi phương thứcÔn tập: thao tác với hình chữ nhật4Dự án: Thú cưng ảo
Định nghĩa thú cưngCho thú cưng ăn7Các trait tiêu chuẩn
Trait DebugTrait DisplayClone và CopyCác trait so sánh bằngÔn tập: Điểm có thể in ra2Tính đóng gói và module
Kiến thức cơ bản về moduleTừ khóa publicTrường riêng tưHàm lấy giá trịHàm thiết lập giá trịÔn tập: tủ khóa an toàn5Kiểu tổng quát
Cấu trúc tổng quátPhương thức tổng quátNhiều kiểu tổng quátHàm tổng quátÔn tập: điểm tọa độTự luyện tập: Trình biên dịch Rust online