title | excerpt | categories | tags | toc | ||
---|---|---|---|---|---|---|
读 Advanced Swift (4.0) 第一篇 |
术语、风格指南 |
|
|
true |
-
如果结构体中包含引用类型,在将结构体赋值给一个新变量的复制行为中,引用类型的内容不会自动复制一份,只有引用本身会被复制。这种复制的行为被称作浅复制(shallow copy)
Data 是对 NSData 的封装,当 Data 结构体发生改变的时候会对 NSData 做深复制,使用 "写时复制"的技术保证操作的高效
-
数组这样的集合类型也是对引用类型的封装,同样使用了
copy-on-write
。如果数组的元素为引用类型的话,数组复制时元素对象本身不会被复制,而是复制引用。数组的元素为值语义时,数组才有值语义
-
有些类在创建之后就不可能再改变它的内部状态,这种情况下,即使它们是类,它们依然拥有值语义。
只有被标记为 final 的类才能保证不被子类化,不会被添加可变状态
-
一个函数,如果接受函数类型作为参数或者返回值为函数类型,则称之为 高阶函数(higher-order function)
-
函数的派发
- 自由函数(非方法)和在结构体上调用的方法是 静态派发(statically dispatched),这些函数的调用在编译期已经确定, 编译器可以选择**内联(inline)**这些函数,还可以简化或丢弃在编译时就能去定不会被实际执行的代码。
- 类或者协议上的方法可能是动态派发(dynamically dispatched)。编译器在编译时不需要知道那个函数被调用。Swift中,这种动态特性要么由 vtable 来完成,要么通过
selector
和objc_msgSend
来完成,前者的处理方式和Java
或是C++
中类似,而后者只针对@objc
的类和协议上的方法
-
多态的实现
- 子类化和方法重写(overriding)
- 函数重载(overloading)
- 范型
- 优先选择结构体,除非需要使用类的特性或者是引用语义
- 除非设计类被继承使用,否则都标记为
final
- 不写重复的代码。重复类似代码片段应抽取到一个函数里,并且考虑将这个函数转化为协议扩展
- 试着使用
map
和reduce
以增加可读性 - 试着使用不可变值。对于可变的部分可以用函数封装起来,可以把它带来的副作用进行隔离。
- 除非确实需要,否则不要使用
self.
- 尽可能地对现有的类型和协议进行扩展,而不是写一些全局函数。有助于提高可读性,让别人更容易发现你的代码。