Menu
CoddyTech

运行 Screen

本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 53 课,共 61 课。

challenge icon

挑战

简单

恭喜你完成了“文档系统”项目的最后一步!你已经构建了所有独立的部分:Draw trait、TextField、Button 和 Screen。现在,你要让 Screen 能够通过一次方法调用渲染所有组件。

你将通过给 Screen 结构体添加 run 方法来完成项目。这个方法会遍历屏幕中存储的所有组件,并对每个组件调用 draw(),让整个文档系统运行起来。

你的项目文件:

  • draw.rs:包含 draw 方法的 Draw trait。
  • text_field.rs:会打印 Text: {content} 的 TextField 组件。
  • button.rs:会打印 Button: {label} (width: {width}) 的 Button 组件。
  • screen.rs:包含 new 和 add 方法的 Screen 结构体。添加一个 run 方法,该方法接收 &self,并对集合中的每个组件调用 draw()。
  • main.rs:将所有内容组合起来:创建一个 Screen,添加你的组件,然后调用 run() 一次性渲染整个屏幕。

run 方法将渲染逻辑封装在 Screen 内部,让主函数保持简洁明了。你不必在 main 中手动遍历组件,只需调用 screen.run()。

将提供以下输入:

  • 第一行:文本框的内容
  • 第二行:按钮的标签
  • 第三行:按钮的宽度(数字)

你的输出应当按添加组件的顺序,让每个组件各占一行:

Text: Dashboard
Button: Save (width: 120)

亲手试试

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");

    let mut screen = Screen::new();

    let text_field = TextField { content };
    screen.add(Box::new(text_field));

    let button = Button { label, width };
    screen.add(Box::new(button));

    // TODO:将下面的手动遍历改为只调用一次 screen.run()
    for component in &screen.components {
        component.draw();
    }
}

面向对象编程中的所有课

自己练习: Rust 在线编译器