Swift(枚举VS结构VS类)

从客观的c背景出发,枚举,类和结构之类的组件之间的区别对我来说非常明显:Enum是一组命名值,Struct是结构化数据类型,当然Class允许我们创建具有所有POO相关的东西。

当我第一次开始学习Swift时,这有点令人困惑。 从某个时候开始,它们可能看起来很相似。 在许多其他语言中仅使用类的情况下,可以很快找到Structs。

  • 例如:Enums和Structs也可能具有方法或构造函数。

我个人需要一些时间来快速熟悉结构和枚举的扩展功能。

所以为了知道在哪里使用每个。 重要的是要清楚地了解什么使一个人与另一个人不同。 因此,让我们尝试一个接一个地检查它们。

一方面,类之间的枚举和结构之间的主要区别。 是类是引用类型 ,而枚举和结构是值类型

这意味着当您将一个类类型对象分配给另一个对象时。 他们成为
指向同一实例。 因此,当一个被修改时,该修改将应用于另一个:

  class Cat {var name:String init(name:String){self.name = name}} var cat1 = Cat(name:“ Kitty”)var cat2 = cat1cat1.name =“ Oscar” 
//两只猫都是相同的print(“ cat1 name:\(cat1.name),cat2 name:\(cat2.name)”)
// cat1名称:奥斯卡,cat2名称:奥斯卡

而对于结构和枚举,将在每次分配时创建一个新副本:

  struct Cat {var name:String} var cat1 = Cat(name:“ Kitty”)var cat2 = cat1cat1.name =“ Oscar” print(“ cat1 name:\(cat1.name),cat2 name:\(cat2.name )“) 
// cat1名称:奥斯卡,cat2名称:Kitty

结构和枚举是值类型这一事实,除了赋值之外,还有其他一些副作用。

当将Structs创建为常量(使用let)时,整个实例是不可变的。 这意味着我们不允许修改其属性:

  struct Cat {var name:String} let cat1 = Cat(name:“ Kitty”)cat1.name =“ Oscar” //错误:无法分配给属性 

但是上课。 即使其常数,也只有引用是不变的。 虽然可以毫无问题地修改属性:

  class Cat {var name:String?} let cat1 = Cat()cat1.name =“ Oscar” //工作正常 

即使将其声明为变量(var),结构也无法修改自身。 为此,我们需要使用mutating关键字。 不适用于课程:

  struct Cat {private var vaccinated:Bool init(){self.init()} //如果不使用关键字 mutation func vaccinate(){self.vaccinated = true}} var cat1 = Cat()cat1.vaccinate() 

同时具有用于值和引用类型的init方法。 对于值类型,不存在deinit方法。 知道自己不关心引用计数:

  struct Cat {var name:String deinit {}} 
// 编译器错误:只能在类中声明反初始化器

选项仅适用于structs 。 基于属性的“生成的初始化方法”:

  struct Cat {var name:Stringvar age:Int} let cat1 = Cat(name:“ Lucy”,年龄:3) 

还要注意,只有类支持继承:

  struct Pet {var name:String} struct Cat:Pet {} 
//错误:从非协议类型“ Pet”的继承

与类和结构不同,枚举不能包含存储的属性:

 枚举Pet { 

变量名称:字符串
//错误:枚举不能包含存储的属性
}

最后,我们可以说在要表示数据结构的地方使用了结构。 主要是型号。 虽然在大多数其他情况下使用类。

您还可以注意到结构被认为是线程安全的。 由于其价值类型的性质。

感谢您的阅读。 我希望你觉得这有用