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.
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: traitDrawcủa bạn từ các thử thách trước.text_field.rs: thành phầnTextFieldin raText: {content}.button.rs: thành phầnButtonin raButton: {label} (width: {width}).screen.rs: Tạo structScreenchứa một trường công khaicomponentscó kiểuVec<Box<dyn Draw>>. Triển khai hàm liên kếtnewđể tạo một màn hình trống, và phương thứcaddnhận mộtBox<dyn Draw>rồi thêm nó vào vector components.main.rs: Kết hợp tất cả module. Tạo mộtScreen, thêm mộtTextFieldvà mộtButtonvào đó, sau đó duyệt qua các component của màn hình và gọidraw()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
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