WWDC之Advanced Swift
前言
作为Swift
语言高级特性的介绍和深入,本Session
,主要内容为
-
Taking Control of syntax
: 开发者如何基于Swift
进行自定义的语言扩展 -
Generic Programming
: 泛型编程在Swift
的高级应用 -
Swift Model
:Swift
内部架构和编译特性
内容
Taking Control of syntax
-
_
: 匿名参数的使用
用于表示忽略该值,应用场景:
1 遍历
2 函数命名时的外部参数的省略(除了首个参数外都有与函数参数(形参)相同的外部参数,首参数的外部参数默认为匿名参数)
3 以及对其值不关心的情况;// 1 for (key, _) in dictionary { print(key) } // 2 func executeTowTasks(taskA:Task,_ taskB:Task){...} executeTowTasks(Task(),Task()) /*default is executeTowTasks(Task(),taskB:Task())*/ var red,blue: Int (red, _, blue, _) = color.rgba /* not care about the value of green and alpha */
-
Protocol的使用
1 快速声明一个协议,并让某个类型遵守并实现协议的方法.(Swift
中Struct
,Enum
都支持Protocol
的使用)
2 可以使用Protocol
值进行模式匹配// 1 protocol Pullable { func pull() } class Board: Pullable { /*not only class*/ } // 2 if let pullableObject = objec as Pullable { /* pull it */ } else { /* error log */ }
下方为
protocols.png 比如想要自定义对Swift
标准库常用的Protocol列表
print(object)
或者\(object)
的字符串内容,只需遵从Printable
协议,并实现该协议的只读属性description
,返回自定义的字符串即可.Protocol Printable { var description: String {get} } extension Thing Printable { var description: String { return "a thing" } } print(Thing()) // a thing
-
自定义操作符
1 必须先使用operator
声明所定义的操作符
2 所定义的操作符函数必须为全局函数// 1 infix operator ^ {} // 2 func ^ (lhs /* left hand side */ : Int, rhs: Int) -> Int { var total = 1 for _ in 1...rhs { total *= lhs } return total } print(2^3) // 8 <= 2 * 2 * 2
注意:
- 声明自定义操作符时的
infix
表示运算符类型为中缀型(如+,-,*,%),还可以使用prefix
声明为前缀运算符,使用postfix
声明为后缀运算符,内部还可以对运算优先级,结合率是否支持进行设置. - 全局的运算符函数也可以接收函数变量,然后利用另一个参数在内部进行函数的调用,并将其结果返回.
- 声明自定义操作符时的
- 自定义下标
1 首先要使用subscirpt
关键字声明一个有接收参数并有返回参数的下标函数
2 下标函数内部实现set
和get
方法
extension String {
// 1
subscript(a: Int) -> Character? {
// 2
get {
if a > self.characters.count {
return nil // out of index
} else {
return self[self.startIndex.advancedBy(a-1)]
}
}
set {
}
}
}
if let c = "abcd"[1] {
print(c) // "a"
}
Generic Programming
-
快速定义泛型函数
fun peek<T>(value: T) -> T { print(value) return value }
这里的
T
表示实际所传参数的Type
,也可用其他占位符如U
,R
... -
允许对泛型类型参数进行协议约束
func indexOf<T: Equatable>(sought: T,inArray array: [T]) -> Int? { for i in 0..<array.count { if array[i] == sought { return i } } return nil }
让泛型类型T必须遵守
Equatable
协议,使得该类型变量在内部实现中能进行判断操作. -
结合泛型实现闭包递归使用
func sums<T, U>(body:((T) -> U , T) ->U ) -> ((T) -> U) { var result:((T)->U)! result = { x in return body(result, x) } return result } let sum2 = sums{sum2, x in x == 0 ? 0 : x + sum2(x - 1)} let g = sum2(5) print(g) // 5 + 4 + 3 + 2 + 1
此例模仿该
Session
上对factorial
闭包如何结合泛型进行递归调用的实战模仿,实现一个可以累加的闭包.而针对如何实现闭包的简单递归调用实现方案如下var sum: Int -> Int = {$0} sum = { (n:Int) -> Int in if (n == 0) { return 0 } return sum(n-1) + n; } print(sum(5)) // 15
-
利用泛型类型实现自定义对象的
for-in
遍历
首先自定义对象必须实现SequenceType
,GeneratorType
这两个协议,而SequenceType
协议是基于GeneratorType
协议变量实现的,所以先要对GeneratorType
进行实现.
// 1 实现GeneratorType协议
public protocol GeneratorType {
typealias Element
public mutating func next() -> Self.Element?
}
struct CustomGenerator<T>: GeneratorType {
typealias Element = T // 基于类型推断可省略
mutating func next() -> T? {
if items.isEmpty { return nil }
let ret = items[0]
items = items[1..<items.count]
return ret
}
var items: Slice<T> // 能够裁剪的集合
}
// 2 实现Sequence协议
public protocol SequenceType {
typealias Generator : GeneratorType
public func generate() -> Self.Generator
}
extension CustomObject: Sequence {
func generate() -> CustomGenerator<T> {
return CustomGenerator(items[0..<itemCount])
}
}
// 3 实现for-in调用
for i in CustomObject {
....
}
Swift Model
做为一门静态编译语言,对运行时环境的要求小,能与C,Objective-C等语言进行充分交互,Swift
编译生成原始代码,使得在设备上的运行速度十分快速,让App
启动时不再重编译和加载延迟.下图为Swift
优化的编译架构
结尾
作为Swift
语言的高级内容介绍,出现了很多难以理解知识点,以及Swift
语言特性实现,但也收获了几个知识点比如如何实现Swift
闭包的递归;如何自定义下标函数;以及使用一些简单的系统标准库协议来扩展自己的代码.
最后,还是需要多实践多写写Swift
代码,来加深对该语言的理解,再回过头来看一遍这个Session
,应该会有更大的体会和理解.