1. 值类型与引用类型
- 结构体和枚举类型是值类型,类是引用类型。
- 引用类型具有同一性,可以使用“===”来检查两个变量是否确实引用了同一个对象。
- 值类型不存在同一性的问题。例如不能对一个变量判定是否与另一个变量持有相同的数字“2”,而判定他们是否都包含了数字2.
- “===”实际上是判定两个变量是否持有相同的引用。在程序语言中,“==”通常被称为结构相等,“===”被称为指针相等或者引用相等。
- 在swift中,类引用并不是唯一的引用的类型。swift中依然有指针,比如使用withUnsafeMutablePointer就会得到指针。
2. 浅复制(shallow copy)和深复制
- 浅复制会对引用进行复制,但不会复制引用所指向的内容
- 当把一个值类型对另一个值类型进行赋值的时候,对其中的引用类型所做的是浅复制。比如一个struct是一个值类型,但其可能包含各种类型,包括引用类型,当将其赋值给其他值类型的时候,其中的引用类型的关系被复制了,但内容并未被复制,所以即使被复制的是常量,他的引用关系不会变,但引用对象里的内容还是可能会变化。
-
值语义(value semantics): 通过判断是否是深复制,来判断是否具有值语义。
3. 函数
- 函数也是值,你可以将函数赋值给一个变量,或者作为数组的元素存在。
- 函数是引用类型。
- 定义在类中或者协议中的函数被称为方法。方法都有一个隐式的参数self。
- 柯里化函数:如果一个函数不是接收多个参数,而只是一部分参数,并且返回一个接受其余参数的函数的话,这个函数就叫做柯里化函数。
- 自由函数:不是方法的函数。
- 静态派发和动态派发:自由函数和在结构体上调用的方法是静态派发的。对于这些函数的调用,在编译的时候已经确定。类或者协议上的方法是动态派发的。编译器在编译的时候不需要知道哪个函数将被调用。
4. Swift编程风格指南
- 优先选择结构体而不是类,除非你必须使用到类的引用特性。
- 除非你的设计就是为了类被继承,否则所有的类都应该加上final关键字。
- 使用guard来确保提前退出方法。
- 尽量使用不可变值,除非你需要某个值改变,否则都应该使用let。