泛型編程是一種可以保持類型安全性的代碼重用技術,並且一般是指基於類型的的泛型。我們還可以認爲泛型是**多態 (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()
}
}