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 {
变量名称:字符串
//错误:枚举不能包含存储的属性
}
最后,我们可以说在要表示数据结构的地方使用了结构。 主要是型号。 虽然在大多数其他情况下使用类。
您还可以注意到结构被认为是线程安全的。 由于其价值类型的性质。