泛型是面向對象裡另外一個重要的概念,除了多態,它進一步增加的代碼的重用範圍,而對於 Swift 語言來說,泛型貫穿了它的始終。
從 Print() 說起
我們從上課的第一天開始就在使用這個全局函數了,它讓我們得以在屏幕上顯示語句,用起來十分簡單,傳入一個字符串即可。
傳入字符串就顯示字符串,傳入整形就顯示數字……
等等!作為一個函數,它怎麼能接收兩種不同的參數!
好吧我們使用萬能的 cmd 按鈕,點進去看看這個 print() 函數究竟是怎麼聲明的:
1 |
public func print<T>(value: T) |
如果沒有泛型
現在,讓我們來寫一個交換兩個數字的方法(抄自蘋果官方手冊)
1 2 3 4 5 |
func swapTwoInts(inout a: Int, inout _ b: Int) { let temporaryA = a a = b b = temporaryA } |
如果要使用,是這樣用的:
1 2 3 |
var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) |
現在我要交換兩個字符串:
1 2 3 4 5 |
func swapTwoStrings(inout a: String, inout _ b: String) { let temporaryA = a a = b b = temporaryA } |
我還要交換兩個雙精度浮點數:
1 2 3 4 5 |
func swapTwoDoubles(inout a: Double, inout _ b: Double) { let temporaryA = a a = b b = temporaryA } |
也就是說,現在我們分別擁有了 Int,String ,Double 版本的交換位置方法——它們的唯一區別就是類型不同。這不符合我們進行開發的原則——相同的內容重複太多——類型千千萬,還不包括我們自己定義的類型,都這麼交換,那……
使用泛型來救場
1 2 3 4 5 |
func swapTwoValues<T>(inout a: T, inout _ b: T) { let temporaryA = a a = b b = temporaryA } |
這樣,不論是 Int 還是 String,甚至是你自己寫的類型,都可以一步到位了。
1 2 3 4 5 6 7 8 9 |
var someInt = 3 var anotherInt = 107 swapTwoValues(&someInt, &anotherInt) // someInt is now 107, and anotherInt is now 3 var someString = "hello" var anotherString = "world" swapTwoValues(&someString, &anotherString) // someString is now "world", and anotherString is now "hello" |
泛型
我們用 T 來代表一個佔位符——說白了它就是一個通配符,我們不限制傳入類型的參數,唯一的要求就是這兩個參數的類型得是一致的。然後我們在方法的後邊用尖括號<>括起來一個佔位符,代表這個方法是一個泛型方法。
下面,我們再來用泛型實現一個結構體:
1 2 3 4 5 6 7 8 9 |
struct IntStack { var items = [Int]() mutating func push(item: Int) { items.append(item) } mutating func pop() -> Int { return items.removeLast() } } |
這是一個整形的棧——關於棧的概念我們已經講過,面向對象當中的方法執行過程就是在棧中完成的,現在我們寫一個整形的棧,這包含了出棧和入棧的兩個方法——顯然,這個結構體也可以改造成其他類型的棧……我們現在讓它以泛型來實現:
1 2 3 4 5 6 7 8 9 |
struct Stack<Element> { var items = [Element]() mutating func push(item: Element) { items.append(item) } mutating func pop() -> Element { return items.removeLast() } } |
你看,這次我們用 Element 作為佔位符了,關鍵是用<>它可以顯示。
這樣,我們只需要在生成實例的時候表明類型,這個結構體就能夠被對應的類型所使用了。
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/1138.html