泛型编程是一种可以保持类型安全性的代码重用技术,并且一般是指基于类型的的泛型。我们还可以认为泛型是**多态 (polymoyphism) **的一种形式,而多态则是指一个接口或名称可以通过多个类型进行访问的现象。
- 专属多态
通过定义多个同名但是类型不同的方法,这种用法叫做**重载 (overloading) **,或者更技术地说,这是一种 (为了解决排序这个问题而特别设置的) 专属多态 (ad hod polymorphism)。 - 子类型多态
当一个函数或方法接受类 C 作为参数的时候,我们也可以给它传递 C 的派生类,这种用法叫做子类型多态 (subtype polymorphism)。 - 参数化多态
当一个函数 (通过尖括号语法) 接受泛型参数的时候,我们管这个函数叫做泛型函数 (generic function) ,类似地,还有泛型类型和泛型方法。这种用法叫做参数化多态 (parametric polymorphism)。
-结构化的专属多态
定义一个协议并让多个类型实现它,这是另外一种更加结构化的专属多态。
一、泛型类型
可以实现泛型方法、函数、类型,可以通过扩展来为泛型类型添加新的功能(在扩展中可以使用泛型参数,而不必重新声明)。
二、泛型和Any
从实现功能角度来说,泛型与Any类似,但是泛型是拥抱了类型检查,而Any却是逃避了类型检查。
三、基于泛型的设计
// 一个根据数据回调生成User类型的扩展
extension URLSession {
func loadUser(callback: @escaping (Result<User, Error>) -> ()) {
let userURL = webserviceURL.appendingPathComponent("/profile") dataTask(with: userURL) {
data, response, error in
callback( Result {
iflete=error{throwe}
guard let d = data else { throw NoDataError() }
return try JSONDecoder().decode(User.self, from: d)
})
}.resume()
}
}
// 使用泛型进行改造
extension URLSession {
func load<A>(url: URL, parse: @escaping (Data) throws -> A,
callback: @escaping (Result<A, Error>) -> ()) {
dataTask(with: url) { data, response, error in
callback( Result {
if let e = error{ throw e}
guard let d = data else { throw NoDataError() }
return try parse(d)
})
}.resume()
}
}