一叠纷、以泛型為參數(shù)的函數(shù)
泛型是Swift語言強(qiáng)大的核心窖贤,泛型是對類型的抽象愕贡,使用泛型開發(fā)者可以更加靈活方便的表達(dá)代碼意圖草雕。我們知道,有參函數(shù)的參數(shù)必須有一個明確的參數(shù)類型固以,有些時候開發(fā)者會遇到這樣一種情況墩虹,編寫一個函數(shù)用于交換兩個變量的值,由于變量有類型之分憨琳,實現(xiàn)相同的功能诫钓,可能需要重載成多個函數(shù)來實現(xiàn),這大大浪費(fèi)了開發(fā)成本篙螟,使用泛型菌湃,可以完美的解決這個問題,示例代碼如下:
func exchange<T>(inout param1:T,inout param2:T){
let tmp = param1
param1 = param2
param2 = tmp
}
var p1 = "15"
var p2 = "40"
exchange(&p1, param2: &p2)
上面的方法可以實現(xiàn)對任意相同類型變量的交換遍略,函數(shù)參數(shù)中使用泛型惧所,需要在函數(shù)名后的<>中定義參數(shù)占位符,如有多個參數(shù)占位符墅冷,用逗號隔開即可纯路。
二、泛型在類型中的應(yīng)用
泛型除了可以作為函數(shù)的參數(shù)寞忿、返回值外驰唬,在定義類型時,靈活應(yīng)用泛型也可以解決很多十分棘手的問題,例如實現(xiàn)一個棧結(jié)構(gòu)的集合類型叫编,示例代碼如下:
struct Stack<ItemType> {
var items:[ItemType] = []
mutating func push(param:ItemType) {
self.items.append(param)
}
mutating func pop()->ItemType{
return self.items.removeLast()
}
}
//整型棧
var obj1 = Stack<Int>()
obj1.push(1)
obj1.pop()
//字符串棧
var obj2 = Stack<String>()
obj2.push("HS")
obj2.pop()
在對使用了泛型的類型進(jìn)行擴(kuò)展時辖佣,不需要在使用<>進(jìn)行泛型的定義,直接使用原定義的泛型占位符即可搓逾,示例如下:
extension Stack{
func getArray() -> [ItemType] {
return items
}
}
有時候卷谈,開發(fā)者需要對泛型進(jìn)行一些約束,例如只允許此泛型是繼承自某個類或者實現(xiàn)了某個協(xié)議霞篡,示例代碼如下:
class MyClass {
}
//只有MyClass的子類可以進(jìn)行Stack棧的創(chuàng)建
struct Stack<ItemType:MyClass> {
var items:[ItemType] = []
mutating func push(param:ItemType) {
self.items.append(param)
}
mutating func pop()->ItemType{
return self.items.removeLast()
}
}
在協(xié)議中世蔗,可以使用另一種方式來進(jìn)行泛型編程,使用associatedtype關(guān)鍵字可以進(jìn)行類型關(guān)聯(lián)朗兵,示例如下:
protocol MyProtocol {
//實現(xiàn)協(xié)議時才指定類型
associatedtype ItemType
var param:ItemType {get set}
}
class MyClass:MyProtocol {
//由于Swift可以自動識別類型 這是MyProtocol中的ItemType為Int
var param: Int = 0
}
三污淋、泛型與where子句的結(jié)合使用
使用where子句可以對泛型進(jìn)行更加嚴(yán)格約束,使其符合開發(fā)者需要的邏輯余掖,示例如下:
//T和C都要遵守整型協(xié)議
class MyClassTwo<T,C where T:IntegerType,C:IntegerType> {
var param1:T
var param2:C
init(param1:T,param2:C){
self.param1=param1
self.param2=param2
}
}
var obj3 = MyClassTwo(param1: 1, param2: 1)