MST
星途 面试题库

面试题:Rust中impl块与trait的综合运用

定义一个`trait`叫`Drawable`,包含一个方法`draw`。然后定义两个结构体`Circle`和`Rectangle`,分别包含必要的字段来表示圆形(圆心坐标和半径)和矩形(左上角坐标和宽高)。在各自的`impl`块中为`Circle`和`Rectangle`实现`Drawable` trait 的`draw`方法,简单打印出描述图形的信息(例如对于圆形打印“Drawing a circle with center (x, y) and radius r”,对于矩形打印“Drawing a rectangle with top - left corner (x, y), width w and height h”)。接着创建一个函数`draw_shapes`,接受一个`Vec<Box<dyn Drawable>>`类型的参数,在函数内部遍历该向量并调用每个图形的`draw`方法。请写出完整代码,并解释这里`Box<dyn Drawable>`的作用。
23.1万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义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>的作用

  1. 动态分发Box<dyn Drawable>表示一个指向实现了Drawable trait 的类型的指针。通过这种方式,我们可以在运行时根据对象实际的类型来调用对应的draw方法,实现动态分发。例如在draw_shapes函数中,我们不需要关心具体的图形类型是Circle还是Rectangle,只需要知道它们都实现了Drawable trait 即可调用draw方法。
  2. 统一类型Vec<Box<dyn Drawable>>可以存储不同类型(只要这些类型都实现了Drawable trait)的对象。如果没有Box<dyn Drawable>,我们无法直接将不同类型的对象放入同一个向量中,因为 Rust 要求向量中的元素类型必须一致。Box<dyn Drawable>将不同类型的对象统一成了一种类型,使得这种存储成为可能。