美文网首页
Rust中的三种多态性——枚举+结构体(下)

Rust中的三种多态性——枚举+结构体(下)

作者: L我是小学生 | 来源:发表于2022-03-12 16:37 被阅读0次

0x00 回顾与开篇

多态性(Polymorphism)在很多语言中都存在,比如Java/C#等。有了编程语言的多态性会使我们在工作中更加灵活和方便。当然,Rust也有多态性的特点。在Rust中有三种主要方法来实现多态,我们的目的就是讨论每种方法的优缺点。上一篇文章介绍了Trait的两种方式。今天咱们一起来看最后一种方式——Enum+Struct。

0x01 Enum + Struct

废话不多说,直接上代码。

enum ShapeEnum {
    Rectangle(Rectangle),
    Triangle(Triangle),
    Circle(Circle)
}

struct Rectangle { pub width: f32, pub height: f32 }
struct Triangle { pub side: f32 }
struct Circle { pub radius: f32 }

trait Shape {
    fn perimeter(&self) -> f32;
    fn area(&self) -> f32;
}

impl Shape for ShapeEnum {
    fn perimeter(&self) -> f32 {
        match self {
            ShapeEnum::Rectangle(rect) => rect.perimeter(),
            ShapeEnum::Triangle(tri) => tri.perimeter(),
            ShapeEnum::Circle(circ) => circ.perimeter(),
        }
    }
    fn area(&self) -> f32 {
        match self {
            ShapeEnum::Rectangle(rect) => rect.area(),
            ShapeEnum::Triangle(tri) => tri.area(),
            ShapeEnum::Circle(circ) => circ.area(),
        }
    }
}

impl Shape for Rectangle {
    fn perimeter(&self) -> f32 {
        self.width * 2.0 + self.height * 2.0
    }
    fn area(&self) -> f32 {
        self.width * self.height
    }
}

impl Shape for Triangle {
    fn perimeter(&self) -> f32 {
        self.side * 3.0
    }
    fn area(&self) -> f32 {
        self.side * 0.5 * 3.0_f32.sqrt() / 2.0 * self.side
    }
}

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

这种写法,在我看来应该是比较不错的一种了。但是它有个缺点,每当你需要添加新的变量和方法时,需要在很多地方添加代码。其它为自己的结构体实现 Shapecrate 将无法将它们传递给 ShapeEnum,维护比较麻烦。

0x02 推荐使用一种方式?

在这里,我们通过一个表格来对比下以上三种方式优缺点吧。(表格仅供参考)

内联布局 不浪费内存 混合类型集合 扩展性 易于编写和维护
枚举
Trait泛型
Trait动态
枚举+结构体

上面的表格仅代表个人看法。在工作中,如果变量很小,已知,有限且没有给其它人提供 crate 的需要。我还是比较建议使用枚举。另外,动态调度还是比较推荐使用的,即使它的性能较低,但大多数时候它仍然表现的还是不错的。当然泛型在很多语言中都存在,如果你熟悉了Java/C#等面向对象的语言,我也是比较推荐的。

0x03 小结

我通过3篇文章啰里啰嗦的介绍了Rust中实现多态的3种方式。可能读到这里,有些同学还在纠结我应该使用哪种方式。其实,在我们平时的大多数情况下使用哪一种并不重要,选择自己喜欢的并且适合自己所应用的场景就可以了,并不要被别人的任何言论所束缚,除非你真的是非要挤出那一点性能,我认为Rust的性能已经足够好了。

最近工作比较繁忙,更新有些慢,望大家见谅了!

相关文章

  • Rust中的三种多态性——枚举+结构体(下)

    0x00 回顾与开篇 多态性(Polymorphism)在很多语言中都存在,比如Java/C#等。有了编程语言的多...

  • swift 杂记

    swift 中所有的数据类型都是由三种不同的数据结构(枚举、结构体、类)中的某一种实现的。 枚举和结构体在代码中以...

  • Swift 面向对象 1: 枚举

    //swift语言中将结构体与枚举放在了面向对象的思想中因为枚举、结构体、类工作原理完全相同这三种面向对象的要素都...

  • Swift---10.属性

    属性(类,结构体或枚举中,某一个成员变量,就是该类,结构体或枚举的属性)存储属性 存在于类,结构体中,枚举中不存在...

  • Nested Types

    为了表示更复杂的结构,swift中类、结构体和枚举可以使用内嵌类型 在结构体中嵌套枚举的复杂实例 //Neste...

  • C语言结构体 共同体 枚举

    语言------结构体 枚举学习,有需要的朋友可以参考下。 结构体 枚举 1.局部变量: >定义.在代码块内部定...

  • swift-structure、enumeration、clas

    swift的三种类型:结构体(structure)、枚举(enumeration)、类(class)其中引用类型为...

  • Rust语言教程(9) - if let表达式与枚举进阶

    Rust语言教程(9) - if let表达式与枚举进阶 枚举复习 前面我们介绍了Rust中的枚举类型,以及通过枚...

  • Swift中mutating关键字

    结构体枚举或者协议中,使用mutating修饰的方法,可以在该方法内部修改结构体,枚举,或者协议的属性变量。 对值...

  • Swift方法mutating关键字的本质

    Swift的结构体或者枚举的方法中,如果方法中需要修改当前结构体或者枚举的属性值,则需要再func前面加上muta...

网友评论

      本文标题:Rust中的三种多态性——枚举+结构体(下)

      本文链接:https://www.haomeiwen.com/subject/uvtldrtx.html