文章目录
- Rust的特征对象
- 前言
- 在屏幕上绘制各种UI组件
Rust的特征对象
前言
- 特征对象不像泛型和impl trait这种零成本抽象,特征对象是在runtime时确定具体类型,有一定的性能开销。
- 当我们需要函数参数是一类实现了特定trait的类型时,这时候就要使用特征对象
- 特征对象形式:dyn,可使用&dyn或者Box<dyn>这种形式
- 特征对象和oop语言中的继承很相似,因为Rust没有继承(现代的编程语言如Rust,Go都没有继承,它们认为继承是一种过度设计,被抛弃了)
在屏幕上绘制各种UI组件
首先定义了Button和SelectBox类型,他们都具有Draw特性。然后Screen的components组件包含了所有的UI组件(即实现了Draw特征的类型),重点就是这个Box<dyn Draw>
// 特征对象
struct Button {
height: i32,
width: i32,
label: String,
}
struct SelectBox {
height: i32,
width: i32,
options: Vec<String>,
}
trait Draw {
fn draw(&self);
}
impl Draw for Button {
fn draw(&self) {
// 绘制button
println!("绘制button, height: {}, width: {}, label: {}", self.height, self.width, self.label);
}
}
impl Draw for SelectBox {
fn draw(&self) {
// 绘制selectbox
println!("绘制selectbox, height: {}, width: {}", self.height, self.width);
}
}
struct Screen {
components: Vec<Box<dyn Draw>>,
}
impl Screen {
fn run(&self) {
for c in self.components.iter() {
c.draw();
}
}
}
fn main() {
let screen = Screen {
components: vec![
Box::new(Button {
height: 50,
width: 50,
label: "xwphs".to_string(),
}),
Box::new(SelectBox {
height: 30,
width: 10,
options: vec![String::from("yes"), String::from("no"), String::from("maybe")],
}),
]
};
screen.run();
}