泛型代碼可以讓你寫出根據自我需求定義、適用于任何類型的,靈活且可重用的函數和類型。它可以讓你避免重復的代碼,用一種清晰和抽象的方式來表達代碼的意圖。
泛型是 Swift 強大特征中的其中一個,許多 Swift 標準庫是通過泛型代碼構建出來的。事實上,泛型的使用貫穿了整本語言手冊,只是你沒有發現而已。例如,Swift 的數組和字典類型都是泛型集。你可以創建一個Int數組,也可創建一個String數組,或者甚至于可以是任何其他 Swift 的類型數據數組。同樣的,你也可以創建存儲任何指定類型的字典(dictionary),而且這些類型可以是沒有限制的。
泛型所解決的問題
這里是一個標準的,非泛型函數swapTwoInts,用來交換兩個Int值:
泛型函數:類型參數
泛型函數可以訪問任何數據類型,如:'Int' 或 'String'.
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")
Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics
函數 exchange()用于交換其在上述方案中描述和<T>被用作類型參數值。這是第一次,函數 exchange()被調用返回Int值,第二次調用函數 exchange()將返回String值。多參數類型可包括用逗號分隔在尖括號內。
類型參數被命名為用戶定義來了解擁有類型參數的目的。 Swift 提供<T>作為泛型類型參數的名字。 但是型像數組和字典參數也可以命名為鍵,值,以確定它們輸入屬于“字典”。
泛型類型
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
let deletetos = tos.pop()
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
擴展泛型類型
擴展堆棧屬性要知道該項目的頂部包含在“extension” 關鍵字。
mutating func pop() -> T {
return items.removeLast()
}
}
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
extension TOS {
var first: T? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
if let first = tos.first {
println("The top item on the stack is /(first).")
}
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
在堆棧頂部的項目命名類型參數。
類型約束
Swift 語言允許“類型約束”指定類型參數是否從一個特定的類繼承,或者確保協議一致性標準。
var numb1 = 100
var numb2 = 200
println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")
var str1 = "Generics"
var str2 = "Functions"
println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")
Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics
關聯類型
Swift 允許相關類型,并可由關鍵字“typealias”協議定義內部聲明。
struct TOS<T>: Container {
// original Stack<T> implementation
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(item: T) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
var tos = TOS<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Type Parameters")
println(tos.items)
tos.push("Naming Type Parameters")
println(tos.items)
[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]
Where 子句
類型約束使用戶能夠定義與泛型函數或類型相關聯的類型的參數要求。用于定義相關類型的 'where' 子句聲明為類型參數列表的一部分要求。 “where”關鍵字類型參數后面類型和相關類型之間的相關類型的限制,平等關系的列表后放置。
struct Stack<T>: Container {
// original Stack<T> implementation
var items = [T]()
mutating func push(item: T) {
items.append(item)
}
mutating func pop() -> T {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(item: T) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> T {
return items[i]
}
}
func allItemsMatch<
C1: Container, C2: Container
where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
(someContainer: C1, anotherContainer: C2) -> Bool {
// check that both containers contain the same number of items
if someContainer.count != anotherContainer.count {
return false
}
// check each pair of items to see if they are equivalent
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// all items match, so return true
return true
}
var tos = Stack<String>()
tos.push("Swift")
println(tos.items)
tos.push("Generics")
println(tos.items)
tos.push("Where Clause")
println(tos.items)
var eos = ["Swift", "Generics", "Where Clause"]
println(eos)
[Swift][Swift, Generics][Swift, Generics, Where Clause][Swift, Generics, Where Clause]
新聞熱點
疑難解答
圖片精選