泛型

使用泛型代码,你可以 写出可重用的函数和数据结构,只要它们满足你所定义的约束,它们就能够适用于各种类型。
比如,像是 Array 和 Set 等多个类型,实际上是它们中的元素类型就是泛型抽象。
我们也可以 创建泛型方法,它们可以对输入或者输出的类型进行泛型处理。
func identity(input: A) -> A 就定义了一个可以作用于任意类型 A 的函数。
某种意义上,我们甚至可以认为带有关联类型的协议是 “泛型协议”。关联类型允许我们对特定的实现进行抽 象。IteratorProtocol 协议就是一个这样的例子:它所生成的 Element 就是一个泛型。

泛型编程的目的是表达算法或者数据结构所要求的核心接口。
使用泛型数据类型来重构代码,能使它们易于测试,更加灵活。

重载

重载:拥有同样名字,但是参数或返回类型不同的多个方法互相称为重载方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func raise(_ base: Double, to exponent: Double) -> Double {
return pow(base, exponent)
}
func raise(_ base: Float, to exponent: Float) -> Float {
return powf(base, exponent)
}
let double = raise(2.0, to: 3.0)
print(double) // 8.0
print(type(of: double)) // Double
let float:Float = raise(2.0, to: 3.0)
print(float) // 8.0
print(type(of: float)) // Float

Swift 有一系列的复杂规则来确定到底使用哪个重载函数,这套规则基于函数是否是泛型,以及传入的参数是怎样的类型来确定使用优先级。整套规则十分复杂,不过它们可以被总结为一句话,那就是 “选择最具体的一个”。也就是说,非通用的函数会优先于通用函数被使用。

重载的使用是在编译期间静态决定的。也就是说,编译器会依据变量的静态类型来决定要调用哪一个重载,而不是在运行时根据值的动态类型来决定。

泛型

泛型编程让我们的资源类型更加简单,耦合更少,这也让测试更加容易

1、创建泛型数据类型,泛型函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct Resource<A> {
let path: String
let parse: (Any) -> A?
let webserviceURL : URL = URL(string: "https://baidu.com")!
}
extension Resource {
func loadSynchronously(callback: (A?) -> ()) {
let resourceURL = webserviceURL.appendingPathComponent(path)
let data = try? Data(contentsOf: resourceURL)
let json = data.flatMap {
try? JSONSerialization.jsonObject(with: $0, options: []) }
callback(json.flatMap(parse))
}
}
struct User{
var name:String?
var age = 0
}
// 辅助函数: 将一个 Any 转换为一个 Any 的数组
func jsonArray<A>(_ transform: @escaping (Any) -> A?) -> (Any) -> [A]? {
return { array in
guard let array = array as? [Any] else {
return nil
}
return array.flatMap(transform)}
}
let usersResource: Resource<[User]> =
Resource(path: "/users", parse: jsonArray(User.init))

2、标准库中的 min函数

1
2
3
4
T是泛型参数
func min<T: Comparable>(_ x: T, _ y: T) -> T {
return y < x ? y : x
}

3、全模块优化 之 泛型特化
Swift 中有一个叫做 @_specialize 的半官方标签

1
2
3
4
5
@_specialize(Int)
@_specialize(String)
public func min<T: Comparable>(_ x: T, _ y: T) -> T {
return y < x ? y : x
}

打赏支持一下呗!