Menu
CoddyTech

Struct Screen

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

challenge icon

Thử thách

Dễ

Đã đến lúc kết hợp tất cả thành phần giao diện người dùng của bạn! Bạn sẽ tạo một struct Screen có thể chứa tập hợp các thành phần có thể vẽ khác nhau bằng cách dùng các đối tượng trait. Đây là lúc sức mạnh của Vec<Box<dyn Draw>> thực sự phát huy: một tập hợp quản lý nhiều kiểu thành phần.

Bạn sẽ thêm một module mới vào dự án đang phát triển:

  • draw.rs: trait Draw của bạn từ các thử thách trước.
  • text_field.rs: thành phần TextField in ra Text: {content}.
  • button.rs: thành phần Button in ra Button: {label} (width: {width}).
  • screen.rs: Tạo struct Screen chứa một trường công khai components có kiểu Vec<Box<dyn Draw>>. Triển khai hàm liên kết new để tạo một màn hình trống, và phương thức add nhận một Box<dyn Draw> rồi thêm nó vào vector components.
  • main.rs: Kết hợp tất cả module. Tạo một Screen, thêm một TextField và một Button vào đó, sau đó duyệt qua các component của màn hình và gọi draw() trên từng component.

Screen cần lưu các đối tượng trait, vì vậy bạn sẽ dùng từ khóa dyn với trait Draw. Phương thức add cần nhận &mut self vì nó sửa đổi vector components.

Chương trình sẽ cung cấp các đầu vào sau:

  • Dòng đầu tiên: nội dung của trường văn bản
  • Dòng thứ hai: nhãn của nút
  • Dòng thứ ba: chiều rộng của nút (dưới dạng số)

Đầu ra của bạn cần hiển thị mỗi thành phần trên một dòng riêng, theo thứ tự chúng được thêm vào:

Text: Hello
Button: Click Me (width: 80)

Tự làm thử

mod draw;
mod text_field;
mod button;
mod screen;

use draw::Draw;
use text_field::TextField;
use button::Button;
use screen::Screen;

pub struct Label {
    pub text: String,
}

impl Draw for Label {
    fn draw(&self) {
        println!("{}", self.text);
    }
}

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

    let mut input2 = String::new();
    std::io::stdin().read_line(&mut input2).expect("Failed to read line");
    let label = input2.trim().to_string();

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

    // TODO: Tạo Screen bằng Screen::new()
    // TODO: Thêm TextField được bọc trong Box::new() vào screen
    // TODO: Thêm Button được bọc trong Box::new() vào screen
    // TODO: Duyệt qua screen.components và gọi draw() cho từng phần tử
}

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