Generic 泛型
目的在於「消弭因為不同資料型態,而重複實作相同的演算法」,在這邊會分別介紹 Generic Functions
、Generic types
、Type Constraint
、Associated Types
前言
泛型的宣告,是由角括號 <>
將 Generic Parameter 包裹起來,若有多個 parameters,則以,
分隔
<GenericA, GenericeB>
泛型有幾個特性:
- 只是一個代名詞,不代表任何實際型別
- 直接寫在該宣告名稱後面(如 function name 之後)
- Type Parameter 可使用任意的合法 identifier,常見如 <T>、<U>,慣例會用大寫開頭,表示是一個 type,而非 value
Generic Functions
例如有兩種不同廠牌,外觀也不一樣的車子,隸屬不同的 struct,不管哪種車子都需要啟動。但由於各廠牌差異過大,需要定義多個實作相同的 function,每台車才可正常啟動
透過 Generic Function 可以將 start(_:) 改為支援任何 data types 的泛型版本
Generic Types
這邊的寫法只能為單一廠牌的車建立庫存
透過 Generic Type 可以為不同廠牌的車建立不同的庫存
- 1 — >虛擬的型別
- 2 — >Array 儲存的資料型別
- 3 — >function 的參數型別
- 4 — >function 的 return type
定義完成後,若希望使用 CarList 這個 Generic Type 時,我們必須明確告訴 compiler 這個 CarList Instance 會儲存何種型別
var car = CarList<String>()
Type Constraints
有時候可能需要傳入的型別有實作特定方法,泛型可以透過設置 Type Constraints,確保傳入型別符合需求。
1、為兩種車子加上一些功能
2、定義兩個 Generic functions ,每個 functions 都有相對應的 Type Constraints,確保傳入的型別符合要求
3、實作後會發現編譯失敗,因為 Audi 並沒有遵守 HeadphoneJack
let audi = Audi()let bnw = BNW()charge(car: audi)charge(car: bnw)listenMusicWhileCharging(car: audi) //編譯失敗listenMusicWhileCharging(car: bnw)
Associated Types
protocol 如果想實現 generic 的話,可以使用 associated type
來替代
例如,設定 cell 的資料,可以透過以下方式,去實作設定不同型別的資料
associatedtype
除了提供 protocol 相關的 Generic Type 之外,也可以直接提供 default type
protocol GotDefaultAssociatedType {associatedtype SomeType = Double // 提供 default type 為 Double}