当前位置:   article > 正文

Rust面试宝典第10题:绘制各种图形

Rust面试宝典第10题:绘制各种图形

题目

        我们需要编写一个图形相关的应用程序,并处理大量图形(Shape)信息,图形有矩形(Rectangle)、正方形(Square)、圆形(Circle)等种类。应用程序需要计算这些图形的面积,并且可能需要在某个设备上进行显示(使用在标准输出上打印信息的方式作为示意)。

        (1)请使用面向对象的设计方法对以上需求进行设计,编写可能需要的结构体及其实现。

        (2)请给出实现以上功能的示例性代码,从某处获取图形信息并且进行计算和显示。

解析

        这道题主要考察应聘者对结构体、特征、封装等知识的整体理解和把控能力,涉及的知识点比较多,对于Rust初学者还是有一定难度的。

        先来看第一道小题,我们需要使用面向对象的设计方法来进行类的封装和实现。根据题目所述,图形有矩形(Rectangle)、正方形(Square)、圆形(Circle)等种类,那么,如何进行封装呢?矩形、正方形、圆形虽然形状不同,但它们都有一些基本的共同的属性,比如:具有周长、面积等性质。因此,我们可以先定义一个图形的Trait,在这个Trait中定义一些通用的属性和方法,具体可参考下面的示例代码。

  1. trait Shape {
  2. fn area(&self) -> f64;
  3. fn display(&self);
  4. }

        接下来,我们定义了下面名为Rectangle的结构体。这个结构体代表了一个矩形,包含两个关键的属性:width(宽度)和height(高度)。这两个属性都是64位浮点数类型(f64),这意味着矩形的尺寸可以是小数,从而提供了更高的精度和灵活性。随后,通过impl Shape for Rectangle语句,代码为Rectangle类型实现了Shape trait。这个实现包括了两个方法。

        area方法:计算矩形的面积,通过将宽度乘以高度得出结果。这个方法没有副作用,它接收一个自身的引用(&self),并返回一个f64类型的面积值。

        display方法:用于显示矩形的信息。这个方法使用println!宏来格式化并打印出矩形的宽度、高度和面积。值得注意的是:在打印面积时,它直接调用了之前定义的area方法,这展示了方法之间的互相调用以及代码的复用。

  1. struct Rectangle {
  2. width: f64,
  3. height: f64,
  4. }
  5. impl Shape for Rectangle {
  6. fn area(&self) -> f64 {
  7. self.width * self.height
  8. }
  9. fn display(&self) {
  10. println!(
  11. "Rectangle: width = {}, height = {}, area = {}",
  12. self.width,
  13. self.height,
  14. self.area()
  15. );
  16. }
  17. }

        正方形结构体Square的实现与矩形结构体相似,但其只有一个side的属性。具体的实现,可参考下面的示例代码。

  1. struct Square {
  2. side: f64,
  3. }
  4. impl Shape for Square {
  5. fn area(&self) -> f64 {
  6. self.side * self.side
  7. }
  8. fn display(&self) {
  9. println!("Square: side = {}, area = {}", self.side, self.area());
  10. }
  11. }

        最后,我们来封装圆形结构体Circle。Circle也只有一个属性,就是圆形的半径radius。具体的实现,可参考下面的示例代码。

  1. struct Circle {
  2. radius: f64,
  3. }
  4. impl Shape for Circle {
  5. fn area(&self) -> f64 {
  6. std::f64::consts::PI * self.radius * self.radius
  7. }
  8. fn display(&self) {
  9. println!("Circle: radius = {}, area = {}", self.radius, self.area());
  10. }
  11. }

        在第二道小题中,要求应聘者从某处获取图形信息并且进行计算和显示。实际上,就是编写一个使用上述图形类的简单程序。在下面的示例代码中,我们首先创建了一个名为shapes的向量(Vec),该向量中存储了不同类型的形状对象。这些对象都被装箱(Box::new)并转换为Box<dyn Shape>类型的trait对象。这意味着,尽管这些形状在内存中的具体表示可能不同,但它们都实现了Shape trait,因此可以以一种统一的方式被处理。

        最后,代码通过一个for循环遍历shapes向量中的每个形状对象,并调用其display方法。由于每个对象都实现了Shape trait,因此它们都拥有display方法,这使得能够统一地处理和显示不同形状的信息。在循环中调用shape.display()时,Rust会在运行时动态地确定应该调用哪个具体实现的display方法。

  1. fn main() {
  2. let shapes = vec![
  3. Box::new(Rectangle { width: 4.0, height: 5.0 }) as Box<dyn Shape>,
  4. Box::new(Square { side: 6.0 }) as Box<dyn Shape>,
  5. Box::new(Circle { radius: 3.0 }) as Box<dyn Shape>,
  6. ];
  7. for shape in shapes {
  8. shape.display();
  9. }
  10. }

        执行上述示例代码后,其打印输出如下。

  1. Rectangle: width = 4, height = 5, area = 20
  2. Square: side = 6, area = 36
  3. Circle: radius = 3, area = 28.274333882308138

总结

        在本题中,我们学习了Rust中面向对象编程的一些关键概念,包括:多态性、Trait对象的使用以及动态方法分发。它允许程序员以一种灵活且类型安全的方式处理不同类型的对象,同时保持代码的简洁性和可读性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/553636
推荐阅读
相关标签
  

闽ICP备14008679号