Swift 泛型
Swift 提供了泛型讓你寫出靈活且可重複使用的函數和類型。
Swift 標準函式庫是透過泛型程式碼建構出來的。
Swift 的陣列和字典類型都是泛型集合。
你可以建立一個Int數組,也可以建立一個String數組,甚至可以是任何其他 Swift 的類型資料數組。
以下實例是一個非泛型函數exchange 用來交換兩個Int 值:
// 定义一个交换两个变量的函数 func exchange(inout a: Int, inout b: Int) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("交换前数据: \(numb1) 和 \(numb2)") exchange(&numb1, b: &numb2) print("交换后数据: \(numb1) 和 \(numb2)")
以上程式執行輸出結果為:
交换前数据: 100 和 200 交换后数据: 200 和 100
泛型函數可以存取任何類型,如Int 或String。
以下實例是一個泛型函數exchange 用來交換兩個Int 和String 值:
func exchange<T>(inout a: T, inout b: T) { let temp = a a = b b = temp } var numb1 = 100 var numb2 = 200 print("交换前数据: \(numb1) 和 \(numb2)") exchange(&numb1, b: &numb2) print("交换后数据: \(numb1) 和 \(numb2)") var str1 = "A" var str2 = "B" print("交换前数据: \(str1) 和 \(str2)") exchange(&str1, b: &str2) print("交换后数据: \(str1) 和 \(str2)")
以上程式執行輸出結果為:
交换前数据: 100 和 200 交换后数据: 200 和 100 交换前数据: A 和 B 交换后数据: B 和 A
這個函數的泛型版本使用了佔位類型名字(通常此情況下用字母T來表示)來取代實際類型名稱(如Int、String或Double)。佔位類型名稱沒有提示T必須是什麼類型,但是它提示了a和b必須是同一型別T,而不管T表示什麼型別。只有 exchange(_:_:)函數在每次呼叫時所傳入的實際類型才能決定T所代表的類型。
另一個不同之處在於這個泛型函數名後面跟著的佔位型別名字(T)是用尖括號括起來的(
泛型型別
Swift 允許你定義你自己的泛型類型。執行輸出結果為:
struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("类型参数") print(tos.items) tos.push("类型参数名") print(tos.items) let deletetos = tos.pop()擴充泛型類型當你擴充一個泛型類型的時候(使用extension 關鍵字),你並不需要在擴充功能的定義中提供類型參數清單。
#實例
下面的範例擴展了泛型TOS 類型,為其新增了一個名為first 的唯讀計算屬性,它將會傳回目前堆疊頂端的元素而不會將其從堆疊中移除。的型別參數,或遵循一個特定的協定或協定構成。參數鏈的一部分。結果為:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"]關聯類型實例Swift 中使用typealias 關鍵字來設定關聯類型。多個關聯類型作為協定定義的一部分是非常有用的。類型符合泛型函數或類別的定義約束。
你可以在參數清單中透過where語句定義參數的限制。
你可以寫一個where語句,緊接在在類型參數列表後面,where語句後面跟著一個或多個針對關聯類型的約束,以及(或)一個或多個類型和關聯類型間的等價(equality)關係。
實例
下面的範例定義了一個名為allItemsMatch的泛型函數,用來檢查兩個Container實例是否包含相同順序的相同元素。
如果所有的元素能夠匹配,那麼傳回一個為true的Boolean值,反之則為false。
struct TOS<T> { var items = [T]() mutating func push(item: T) { items.append(item) } mutating func pop() -> T { return items.removeLast() } } var tos = TOS<String>() tos.push("Swift") print(tos.items) tos.push("泛型") print(tos.items) tos.push("类型参数") print(tos.items) tos.push("类型参数名") print(tos.items) // 扩展泛型 TOS 类型 extension TOS { var first: T? { return items.isEmpty ? nil : items[items.count - 1] } } if let first = tos.first { print("栈顶部项:\(first)") }
以上程式執行輸出結果為:
["Swift"] ["Swift", "泛型"] ["Swift", "泛型", "类型参数"] ["Swift", "泛型", "类型参数", "类型参数名"] 栈顶部项:类型参数名