Menu
CoddyTech

Trait Display

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 36 trên 61.

Debug rất hữu ích cho các nhà phát triển khi kiểm tra dữ liệu, còn trait Display được thiết kế để hiển thị nội dung cho người dùng. Trait này cung cấp bộ định dạng {} trong println!. Khác với Debug, Rust không thể tự động suy ra Display. Bạn phải tự triển khai trait này.

Để triển khai Display, bạn cần thêm mô-đun fmt và triển khai phương thức fmt:

use std::fmt;

struct Temperature {
    celsius: f64,
}

impl fmt::Display for Temperature {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}°C", self.celsius)
    }
}

Phương thức (method) fmt nhận một Formatter và trả về fmt::Result. Bạn dùng macro write! để định dạng đầu ra, truy cập các trường của cấu trúc thông qua self.

Bây giờ bạn có thể in struct bằng bộ định dạng {} tiêu chuẩn:

let temp = Temperature { celsius: 23.5 };
println!("{}", temp);  // 23.5°C

Điểm khác biệt chính: đầu ra Debug cho thấy cấu trúc dữ liệu của bạn, hữu ích khi gỡ lỗi, còn đầu ra Display được trình bày chỉn chu và dành cho người dùng cuối. Một struct có thể triển khai cả hai: dùng {:?} để gỡ lỗi và {} để tạo đầu ra gọn gàng.

challenge icon

Thử thách

Dễ

Hãy tạo một hệ thống hiển thị sản phẩm thân thiện với người dùng! Trong khi Debug hiển thị cấu trúc dữ liệu thô, trait Display cho phép bạn tạo đầu ra chỉn chu, dễ đọc, phù hợp với người dùng cuối.

Bạn sẽ sắp xếp code trong hai tệp:

  • product.rs: Định nghĩa một struct Product công khai với hai trường công khai: name (String) và price (f64). Triển khai trait Display cho struct để định dạng theo mẫu {name} - ${price}. Nhớ đưa std::fmt vào và dùng macro write! bên trong phương thức fmt.
  • main.rs: Đưa module product vào và tạo một instance Product bằng các đầu vào được cung cấp. In sản phẩm bằng bộ định dạng {} tiêu chuẩn để hiển thị kết quả tùy chỉnh.

Trait Display yêu cầu bạn tự triển khai phương thức fmt: Rust không thể tự động suy diễn phương thức này như Debug. Nhờ vậy, bạn có toàn quyền kiểm soát cách kiểu dữ liệu của mình hiển thị với người dùng.

Đầu ra của bạn cần hiển thị sản phẩm theo định dạng gọn gàng, thân thiện với người dùng:

{name} - ${price}

Ví dụ, với đầu vào Wireless Mouse và 29.99:

Wireless Mouse - $29.99

Bạn sẽ nhận hai đầu vào: tên sản phẩm và giá (phân tích thành kiểu f64).

Tự làm thử

mod product;

use product::Product;

fn main() {
    let mut name = String::new();
    std::io::stdin().read_line(&mut name).expect("Failed to read line");
    let name = name.trim().to_string();

    let mut price_input = String::new();
    std::io::stdin().read_line(&mut price_input).expect("Failed to read line");
    let price: f64 = price_input.trim().parse().expect("Failed to parse price");

    // TODO: Tạo một instance Product với tên và giá

    // TODO: In sản phẩm ra bằng bộ định dạng {}
}
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