本文参考
前几天收到一个面试邀请,其中一个面试官直接问Swift中“枚举和结构体”有什么区别,当时直接就给问懵逼了。想了半天也没想出来这两样东西需要有区别吗,貌似就不是一类东西,感觉心虚,回来之后特意找来Swift基础查看了一下,我想当时面试官问的应该是“类和结构体”的区别吧,纯属猜测。言归正传:
在swift中类和结构体有许多相似之处,例如相同的定义格式等。总结之,共同之处如下:
定义属性用于存储值
定义方法用于提供功能
定义下标操作使得可以通过下标语法来访问实例所包含的值
定义构造器用于生成初始化值
通过扩展以增加默认实现的功能
实现协议以提供某种标准功能
与结构体相比,类的功能更加强大,
继承允许一个类继承另一个类的特征
类型转换允许在运行时检查和解释一个类实例的类型
析构器允许一个类实例释放任何其所被分配的资源
引用计数允许对一个类的多次引用
定义语法
class SomeClass{
// class definition goes here类的定义方法
}
struct SomeStructure{
// structure definition goes here结构体的定义方法
}
可以看出,在VideoMode的类中使用了Resolution结构体实例
类和结构体实例的生成
上述只是定义了一个类和结构体,结构体和类的使用需要对齐进行实例化,生成结构体和类的实例非常相似:
let someResolution =Resolution()
let someVideoMode =VideoMode()
对于其属性的访问,可以通过点(.)语法来进行,例如:
print("The width of someResolution is\(someResolution.width)")
// 输出 "The width of someResolution is 0"
print("The width of someVideoMode is\(someVideoMode.resolution.width)")
// 输出 "The width of someVideoMode is 0"
接着需要介绍两个非常有用的名词:
值类型 引用类型
值类型:
值类型被赋予给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝。在 Swift 中,所有的结构体和枚举类型都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。
引用类型:
与值类型不同,引用类型在被赋予到一个变量、常量或者被传递到一个函数时,其值不会被拷贝。因此,引用的是已存在的实例本身而不是其拷贝。
总而言之,如何选择使用类或者结构体:
类和结构体的选择
在你的代码中,你可以使用类和结构体来定义你的自定义数据类型。
然而,结构体实例总是通过值传递,类实例总是通过引用传递。这意味两者适用不同的任务。当你在考虑一个工程项目的数据结构和功能的时候,你需要决定每个数据结构是定义成类还是结构体。
按照通用的准则,当符合一条或多条以下条件时,请考虑构建结构体:
该数据结构的主要目的是用来封装少量相关简单数据值。
有理由预计该数据结构的实例在被赋值或传递时,封装的数据将会被拷贝而不是被引用。
该数据结构中储存的值类型属性,也应该被拷贝,而不是被引用。
该数据结构不需要去继承另一个既有类型的属性或者行为。
举例来说,以下情境中适合使用结构体:
几何形状的大小,封装一个width属性和height属性,两者均为Double类型。
一定范围内的路径,封装一个start属性和length属性,两者均为Int类型。
三维坐标系内一点,封装x,y和z属性,三者均为Double类型。
在所有其它案例中,定义一个类,生成一个它的实例,并通过引用来管理和传递。实际中,这意味着绝大部分的自定义数据构造都应该是类,而非结构体。