Switf 中类和结构体有很多共同点:
1. 定义属性用于储存值
2. 定义方法用于提供功能
3. 定义下标用于通过下标语法访问值
4. 定义初始化器用于生成初始化值
5. 通过扩展以增加默认实现的功能
6. 符合协议以对某类提供标准功能
与结构体相比,类还有以下附加功能:
1. 继承允许一个类继承另一个类的特征
2. 类型转换允许在运行时检查和解释一个类实例的类型
3. 取消初始化器允许一个类实例释放任何其所被分配的资源
4. 引用计数允许一个类的多次引用
PS: 结构体总是通过被复制的方式在代码中传递,因此请不要使用引用计数
结构体和枚举都是值类型
值类型被赋予一个变量,常量或者本身被传递给一个函数的时候,实际上操作的是其的拷贝
类是引用类型
与值类型不同, 引用类型在被赋予一个变量, 常量或者被传递到一个函数时, 操作的并不是其拷贝. 因此, 引用的事已存在的实例本身而不是其拷贝
结构体的主要目的:
1.用来封装少量相关简单数据值
2.有理由预计一个结构体实例在赋值或传递时,封装的数据将会被拷贝而不是被引用
3.任何在结构体中存储的值类型属性,也将被拷贝,而不是被引用
4.结构体不需要去继承另一个已存在的数据类型或者行为
例如:
几何形状的大小,封装一个width属性和height属性,两者均为Double类型.
一定范围内的路径,封装一个start属性和length属性,两者均为Int类型
三维坐标系内一个店,封装x , y 和 z属性, 三者均为Double 类型
Array和Dictionary的赋值与拷贝
Swift中的Array和Dictionary均以结构体的形式实现.然而当数组被赋予一个常量或变量,或被传递给一个函数或方法时,其拷贝行为与字典和其他结构体有些许不同.
Dictionary:
无论何时将一个字典实例赋值给一个变量或者常量,或者传递给一个函数或方法, 这个字典都会在赋值或者调用发生时被拷贝.
如果字典实例中所存的键(keys)和或值(values)是值类型(结构体或枚举).当赋值或调用发生时,他们都会被拷贝.相反,如果keys或者values是引用类型,被拷贝的将会是引用,而不是他们引用的类实例或者函数.字典的键和值的拷贝行为与结构体所存储的属性拷贝行为相同.
Array:
当操作数据内容时,Array能提供接近于C语言的性能,并且只在必要时才发生.
如果你将一个Array实例赋值给一个变量或者常量,或者将其作为参数传递给函数或者方法调用,在事件发生时数组的内容不会被拷贝.相反,数组公用相同的元素序列.当你在一个数组内修改某一个元素,修改结果也会在另一个数组显示.
对数组来说,拷贝行为仅仅当操作有可能修改数组长度时才会发生.这种行为包括了附加,插入,删除或者使用范围下标去替换这一范围内的元素.只有当数组拷贝确要发生时,数组内容的行为规则与字典中键值的想同.
确保数组的唯一性
在操作一个数组,或将其传递给函数以及方法调用之前是很有必要先确定这个数组是有一 个唯一拷贝的。通过在数组变量上调用 unshare 方法来确定数组引用的唯一性。(当数组赋给常量时,不能调用 unshare 方法)
如果一个数组被多个变量引用,在其中的一个变量上调用 unshare 方法,则会拷贝此数组,此时这个变量将会有属于它自己的独立数组拷贝。当数组仅被一个变量引用时,则不会有拷贝发生。
强制复制数组
我们通过调用数组的 copy 方法进行强制显性复制。这个方法对数组进行了浅拷贝(shallow copy),并且返回一个包含此拷贝的新数组。
var copiedNames = names.copy
注意:如果你仅需要确保你对数组的引用是唯一引用,请调用 unshare 方法,而不是 copy 方法。unshare 方法仅会在确有必要时才会创建数组拷贝。copy 方法会在任何时候都创建 一个新的拷贝,即使引用已经是唯一引用。