面试题答案
一键面试// 定义Drawable trait
trait Drawable {
fn draw(&self);
}
// 定义Circle结构体
struct Circle {
center_x: f64,
center_y: f64,
radius: f64,
}
// 为Circle实现Drawable trait
impl Drawable for Circle {
fn draw(&self) {
println!("Drawing a circle with center ({}, {}) and radius {}", self.center_x, self.center_y, self.radius);
}
}
// 定义Rectangle结构体
struct Rectangle {
top_left_x: f64,
top_left_y: f64,
width: f64,
height: f64,
}
// 为Rectangle实现Drawable trait
impl Drawable for Rectangle {
fn draw(&self) {
println!("Drawing a rectangle with top - left corner ({}, {}), width {} and height {}", self.top_left_x, self.top_left_y, self.width, self.height);
}
}
// 定义draw_shapes函数
fn draw_shapes(shapes: Vec<Box<dyn Drawable>>) {
for shape in shapes {
shape.draw();
}
}
fn main() {
let circle = Box::new(Circle {
center_x: 0.0,
center_y: 0.0,
radius: 5.0,
});
let rectangle = Box::new(Rectangle {
top_left_x: 1.0,
top_left_y: 1.0,
width: 10.0,
height: 5.0,
});
let mut shapes = Vec::new();
shapes.push(circle);
shapes.push(rectangle);
draw_shapes(shapes);
}
Box<dyn Drawable>
的作用:
- 动态分发:
Box<dyn Drawable>
表示一个指向实现了Drawable
trait 的类型的指针。通过这种方式,我们可以在运行时根据对象实际的类型来调用对应的draw
方法,实现动态分发。例如在draw_shapes
函数中,我们不需要关心具体的图形类型是Circle
还是Rectangle
,只需要知道它们都实现了Drawable
trait 即可调用draw
方法。 - 统一类型:
Vec<Box<dyn Drawable>>
可以存储不同类型(只要这些类型都实现了Drawable
trait)的对象。如果没有Box<dyn Drawable>
,我们无法直接将不同类型的对象放入同一个向量中,因为 Rust 要求向量中的元素类型必须一致。Box<dyn Drawable>
将不同类型的对象统一成了一种类型,使得这种存储成为可能。