一、以泛型為參數(shù)的函數(shù)
泛型是Swift語(yǔ)言強(qiáng)大的核心,泛型是對(duì)類(lèi)型的抽象,使用泛型開(kāi)發(fā)者可以更加靈活方便的表達(dá)代碼意圖。我們知道,有參函數(shù)的參數(shù)必須有一個(gè)明確的參數(shù)類(lèi)型,有些時(shí)候開(kāi)發(fā)者會(huì)遇到這樣一種情況,編寫(xiě)一個(gè)函數(shù)用于交換兩個(gè)變量的值,由于變量有類(lèi)型之分,實(shí)現(xiàn)相同的功能,可能需要重載成多個(gè)函數(shù)來(lái)實(shí)現(xiàn),這大大浪費(fèi)了開(kāi)發(fā)成本,使用泛型,可以完美的解決這個(gè)問(wèn)題,示例代碼如下:
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)上面的方法可以實(shí)現(xiàn)對(duì)任意相同類(lèi)型變量的交換,函數(shù)參數(shù)中使用泛型,需要在函數(shù)名后的<>中定義參數(shù)占位符,如有多個(gè)參數(shù)占位符,用逗號(hào)隔開(kāi)即可。
二、泛型在類(lèi)型中的應(yīng)用
泛型除了可以作為函數(shù)的參數(shù)、返回值外,在定義類(lèi)型時(shí),靈活應(yīng)用泛型也可以解決很多十分棘手的問(wèn)題,例如實(shí)現(xiàn)一個(gè)棧結(jié)構(gòu)的集合類(lèi)型,示例代碼如下:
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()在對(duì)使用了泛型的類(lèi)型進(jìn)行擴(kuò)展時(shí),不需要在使用<>進(jìn)行泛型的定義,直接使用原定義的泛型占位符即可,示例如下:
extension Stack{ func getArray() -> [ItemType] { return items }}有時(shí)候,開(kāi)發(fā)者需要對(duì)泛型進(jìn)行一些約束,例如只允許此泛型是繼承自某個(gè)類(lèi)或者實(shí)現(xiàn)了某個(gè)協(xié)議,示例代碼如下:
class MyClass { }//只有MyClass的子類(lèi)可以進(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é)議中,可以使用另一種方式來(lái)進(jìn)行泛型編程,使用associatedtype關(guān)鍵字可以進(jìn)行類(lèi)型關(guān)聯(lián),示例如下:
protocol MyProtocol { //實(shí)現(xiàn)協(xié)議時(shí)才指定類(lèi)型 associatedtype ItemType var param:ItemType {get set}}class MyClass:MyProtocol { //由于Swift可以自動(dòng)識(shí)別類(lèi)型 這是MyProtocol中的ItemType為Int var param: Int = 0}三、泛型與where子句的結(jié)合使用
使用where子句可以對(duì)泛型進(jìn)行更加嚴(yán)格約束,使其符合開(kāi)發(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)新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注