Screen 结构体
本课属于 Coddy Rust 学习旅程的“面向对象编程”单元。第 52 课,共 61 课。
挑战
简单现在该把所有 UI 组件组合起来了!你将创建一个 Screen 结构体,用 trait 对象保存一组不同的可绘制组件。这正是 Vec<Box<dyn Draw>> 发挥强大作用的地方:用一个集合管理多种组件类型。
你将在不断扩展的项目中添加一个新模块:
draw.rs:你在之前的挑战中创建的Drawtrait。text_field.rs:你的TextField组件,它会打印Text: {content}。button.rs:你的Button组件,它会打印Button: {label} (width: {width})。screen.rs:创建一个Screen结构体,其中包含一个类型为Vec<Box<dyn Draw>>的公共字段components。实现一个创建空屏幕的关联函数new,以及一个接收Box<dyn Draw>并将其添加到组件向量中的add方法。main.rs:组合所有模块。创建一个Screen,向其中添加一个TextField和一个Button,然后遍历屏幕中的组件,并对每个组件调用draw()。
你的 Screen 需要存储 trait 对象,因此要将 dyn 关键字与 Draw trait 一起使用。add 方法应该接收 &mut self,因为它会修改组件向量。
将提供以下输入:
- 第一行:文本字段的内容
- 第二行:按钮的标签
- 第三行:按钮的宽度(数字)
你的输出应按添加顺序将每个组件显示在单独一行:
Text: Hello
Button: Click Me (width: 80)亲手试试
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: 使用 Screen::new() 创建一个 Screen
// TODO: 将用 Box::new() 包装的 TextField 添加到 screen 中
// TODO: 将用 Box::new() 包装的 Button 添加到 screen 中
// TODO: 遍历 screen.components,对每个组件调用 draw()
}面向对象编程中的所有课
自己练习: Rust 在线编译器