Swift編程中的泛型解析。本站提示廣大學習愛好者:(Swift編程中的泛型解析)文章只能為提供參考,不一定能成為您想要的結果。以下是Swift編程中的泛型解析正文
泛型代碼可讓你寫出依據自我需求界說、實用於任何類型的,靈巧且可重用的函數和類型。它可讓你防止反復的代碼,用一種清楚和籠統的方法來表達代碼的意圖。
泛型是 Swift 壯大特點中的個中一個,很多 Swift 尺度庫是經由過程泛型代碼構建出來的。現實上,泛型的應用貫串了整本說話手冊,只是你沒有發明罷了。例如,Swift 的數組和字典類型都是泛型集。你可以創立一個Int數組,也可創立一個String數組,或許乃至於可所以任何其他 Swift 的類型數據數組。異樣的,你也能夠創立存儲任何指定類型的字典(dictionary),並且這些類型可所以沒無限制的。
泛型所處理的成績
這裡是一個尺度的,非泛型函數swapTwoInts,用來交流兩個Int值:
func swapTwoInts(inout a: Int, inout b: Int)
let temporaryA = a
a = b
b = temporaryA
}
這個函數應用寫入讀出(in-out)參數來交流a和b的值,請參考寫入讀出參數。
swapTwoInts函數可以交流b的原始值到a,也能夠交流a的原始值到b,你可以挪用這個函數交流兩個Int變量值:
var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
// 輸入 "someInt is now 107, and anotherInt is now 3"
swapTwoInts函數長短常有效的,然則它只能交流Int值,假如你想要交流兩個String或許Double,就不能不寫更多的函數,如 swapTwoStrings和swapTwoDoublesfunctions,好像以下所示:
func swapTwoStrings(inout a: String, inout b: String) {
let temporaryA = a
a = b
b = temporaryA
}
func swapTwoDoubles(inout a: Double, inout b: Double) {
let temporaryA = a
a = b
b = temporaryA
}
你能夠留意到 swapTwoInts、 swapTwoStrings和swapTwoDoubles函數功效都是雷同的,獨一分歧的地方就在於傳入的變量類型分歧,分離是Int、String和Double。
但現實運用中平日須要一個用途更壯大而且盡量的斟酌到更多的靈巧性單個函數,可以用來交流兩個任何類型值,很榮幸的是,泛型代碼幫你處理了這類成績。(一個這類泛型函數前面曾經界說好了。)
留意: 在一切三個函數中,a和b的類型是一樣的。假如a和b不是雷同的類型,那它們倆就不克不及交換值。Swift 是類型平安的說話,所以它不許可一個String類型的變量和一個Double類型的變量相互交流值。假如必定要做,Swift 將報編譯毛病。
泛型函數:類型參數
泛型函數可以拜訪任何數據類型,如:'Int' 或 'String'.
func exchange<T>(inout a: T, inout b: T) {
let temp = a
a = b
b = temp
}
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)")
當我們應用 playground 運轉下面的法式,獲得以下成果
Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics
函數 exchange()用於交流其在上述計劃中描寫和<T>被用作類型參數值。這是第一次,函數 exchange()被挪用前往Int值,第二次挪用函數 exchange()將前往String值。多參數類型可包含用逗號分隔在尖括號內。
類型參數被定名為用戶界說來懂得具有類型參數的目標。 Swift 供給<T>作為泛型類型參數的名字。 然則型像數組和字典參數也能夠定名為鍵,值,以肯定它們輸出屬於“字典”。
泛型類型
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")
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()
當我們應用 playground 運轉下面的法式,獲得以下成果
[Swift] [Swift, Generics] [Swift, Generics, Type Parameters] [Swift, Generics, Type Parameters, Naming Type Parameters]
擴大泛型類型
擴大客棧屬性要曉得該項目標頂部包括在“extension” 症結字。
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")
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).")
}
當我們應用 playground 運轉下面的法式,獲得以下成果
[Swift] [Swift, Generics] [Swift, Generics, Type Parameters] [Swift, Generics, Type Parameters, Naming Type Parameters]
在客棧頂部的項目定名類型參數。
類型束縛
Swift 說話許可“類型束縛”指定類型參數能否從一個特定的類繼續,或許確保協定分歧性尺度。
func exchange<T>(inout a: T, inout b: T) {
let temp = a
a = b
b = temp
}
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)")
當我們應用 playground 運轉下面的法式,獲得以下成果
Before Swapping Int values are: 100 and 200 After Swapping Int values are: 200 and 100 Before Swapping String values are: Generics and Functions After Swapping String values are: Functions and Generics
聯系關系類型
Swift 許可相干類型,並可由症結字“typealias”協定界說外部聲明。
protocol Container {
typealias ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
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)
當我們應用 playground 運轉下面的法式,獲得以下成果
[Swift] [Swift, Generics] [Swift, Generics, Type Parameters] [Swift, Generics, Type Parameters, Naming Type Parameters]
Where 子句
類型束縛應用戶可以或許界說與泛型函數或類型相干聯的類型的參數請求。用於界說相干類型的 'where' 子句聲明為類型參數列表的一部門請求。 “where”症結字類型參數前面類型和相干類型之間的相干類型的限制,對等關系的列表後放置。
protocol Container {
typealias ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
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)
當我們應用 playground 運轉下面的法式,獲得以下成果
[Swift] [Swift, Generics] [Swift, Generics, Where Clause] [Swift, Generics, Where Clause]