23.泛型
泛型代碼讓你能夠根據自定義的需求,編寫出適用于任意類型、靈活可重用的函數及類型。它能讓你避免代碼的重復,用一種清晰和抽象的方式來表達代碼的意圖。
1.泛型所解決的問題
//先看一個示例 func swapTwoInts(inout a: Int, inout _ b: Int) {let temporaryA = a;a = b;b = temporaryA; }上面的函數實現了交換兩個 Int 變量的值的功能,但是它只能交換 Int 值,如果你想要交換兩個 String 值或者 Double值,就不得不寫更多的函數。
?2.泛型函數
//問題解決 func swapTwoValues<T>(inout a: T, inout _ b: T) {//swap(&a , &b); //系統的函數,等效于下面三行代碼let temporaryA = a;a = b;b = temporaryA; }//交換Int型 var someInt = 3; var anotherInt = 107; swapTwoValues(&someInt, &anotherInt); print("\(someInt), \(anotherInt)");//交換String型 var someString = "hello"; var anotherString = "world"; swapTwoValues(&someString, &anotherString); print("\(someString), \(anotherString)");3.類型參數
- 在上面的 例子中,占位類型 T 是類型參數的一個例子。類型參數指定并命名一個占位類型,并且緊隨在函數名后面,使用一對尖括號括起來(例如 <T>)。
- 一旦一個類型參數被指定,你可以用它來定義一個函數的參數類型(例如 swapTwoValues(_:_:) 函數中的參數 a 和 b),或者作為函數的返回類型,還可以用作函數主體中的注釋類型。在這些情況下,類型參數會在函數調用時被實際類型所替換。(在上面的 swapTwoValues(_:_:) 例子中,當函數第一次被調用時,T 被 Int 替換,第二次調用時,被 String 替換。)
- 你可提供多個類型參數,將它們都寫在尖括號中,用逗號分開。
4.命名類型參數
- 在大多數情況下,類型參數具有一個描述性名字,例如 Dictionary<Key, Value> 中的 Key 和 Value,以及 Array<Element> 中的 Element,這可以告訴閱讀代碼的人這些類型參數和泛型函數之間的關系。然而,當它們之間沒有有意義的關系時,通常使用單個字母來命名,例如 T、U、V。
5.泛型類型
//自定義泛型類型---棧 struct Stack<Element> {var items = [Element]();mutating func push(item: Element){items.append(item);}mutating func pop() -> Element{return items.removeLast();} }//String類型的Stack var stackOfStrings = Stack<String>(); stackOfStrings.push("uno"); stackOfStrings.push("dos"); stackOfStrings.pop(); stackOfStrings.pop();//Int類型的Stack var stackOfInt = Stack<Int>(); stackOfInt.push(3); stackOfInt.pop();6.擴展一個泛型類型
- 當你擴展一個泛型類型的時候,你并不需要在擴展的定義中提供類型參數列表。原始類型定義中聲明的類型參數列表在擴展中可以直接使用,并且這些來自原始類型中的參數名稱會被用作原始定義中類型參數的引用。
7.類型約束
- 類型約束可以指定一個類型參數必須繼承自指定類,或者符合一個特定的協議或協議組合。
? 類型約束語法:
//TODO:類型約束語法func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U){// 這里是泛型函數的函數體部分 }//TODO:字典定義示例public struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible{}類型約束示例:
func findIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int? {for (index, value) in array.enumerate(){//如果不對T加類型約束Equatable,這里是不能直接用==進行比較的if value == valueToFind{return index;}}return nil; }let doubleIndex = findIndex([3.14159, 0.1, 0.25], 9.3); let stringIndex = findIndex(["Mike", "Malcolm", "Andrea"], "Andrea");8.關聯類型
- 定義一個協議時,有的時候聲明一個或多個關聯類型作為協議定義的一部分將會非常有用。關聯類型為協議中的某個類型提供了一個占位名(或者說別名),其代表的實際類型在協議被采納時才會被指定。你可以通過 associatedtype 關鍵字來指定關聯類型。
?
?
?
轉載于:https://www.cnblogs.com/LeeGof/p/5682927.html
總結
- 上一篇: 仓库如何盘点 打印扫描一体PDA盘点机提
- 下一篇: SU Demos-05Sorting T