MST

星途 面试题库

面试题:Rust结构体二元运算符重载与trait对象及类型擦除

假设有一个trait `Shape`,包含方法 `area` 用于计算形状的面积。定义两个结构体 `Rectangle` 和 `Circle` 都实现 `Shape` trait。现在创建一个新的trait `AddShape`,为实现 `Shape` 的类型重载 `+` 运算符,使得 `+` 运算符的结果表示两个形状合并后的新形状(例如,矩形与矩形相加可以是拼接后的大矩形,圆与圆相加可以是覆盖后的新圆等,具体逻辑自定),返回值也是实现 `Shape` trait 的类型。这里需要处理类型擦除问题,最终可以将不同形状相加的结果存储在 `Vec<Box<dyn Shape>>` 中。请给出完整的Rust代码实现。
41.1万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
trait Shape {
    fn area(&self) -> f64;
}

struct Rectangle {
    width: f64,
    height: f64,
}

impl Shape for Rectangle {
    fn area(&self) -> f64 {
        self.width * self.height
    }
}

struct Circle {
    radius: f64,
}

impl Shape for Circle {
    fn area(&self) -> f64 {
        std::f64::consts::PI * self.radius * self.radius
    }
}

trait AddShape {
    fn add(&self, other: &Self) -> Box<dyn Shape>;
}

impl AddShape for Rectangle {
    fn add(&self, other: &Self) -> Box<dyn Shape> {
        let new_width = self.width + other.width;
        let new_height = self.height + other.height;
        Box::new(Rectangle {
            width: new_width,
            height: new_height,
        })
    }
}

impl AddShape for Circle {
    fn add(&self, other: &Self) -> Box<dyn Shape> {
        let new_radius = (self.radius * self.radius + other.radius * other.radius).sqrt();
        Box::new(Circle {
            radius: new_radius,
        })
    }
}

fn main() {
    let rect1 = Rectangle { width: 5.0, height: 3.0 };
    let rect2 = Rectangle { width: 2.0, height: 4.0 };
    let circle1 = Circle { radius: 3.0 };
    let circle2 = Circle { radius: 4.0 };

    let mut shapes: Vec<Box<dyn Shape>> = Vec::new();

    shapes.push(rect1.add(&rect2));
    shapes.push(circle1.add(&circle2));

    for shape in shapes {
        println!("Area: {}", shape.area());
    }
}