日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

23.泛型

發布時間:2024/4/15 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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,這可以告訴閱讀代碼的人這些類型參數和泛型函數之間的關系。然而,當它們之間沒有有意義的關系時,通常使用單個字母來命名,例如 TUV。

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.擴展一個泛型類型

  • 當你擴展一個泛型類型的時候,你并不需要在擴展的定義中提供類型參數列表。原始類型定義中聲明的類型參數列表在擴展中可以直接使用,并且這些來自原始類型中的參數名稱會被用作原始定義中類型參數的引用。
struct Stack<Element> {var items = [Element]();mutating func push(item: Element){items.append(item);}mutating func pop() -> Element{return items.removeLast();} }extension Stack {var topItem: Element?{return items.isEmpty ? nil : items[items.count - 1];} }var stackOfStrings = Stack<String>(); stackOfStrings.push("uno");if let topItem = stackOfStrings.topItem {print("The top item on the stack is \(topItem)."); //"The top item on the stack is uno.\n" }

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 關鍵字來指定關聯類型。
protocol Container {associatedtype ItemType;var count: Int { get };subscript(i: Int) -> ItemType { get };mutating func append(item: ItemType); }struct Stack<Element>: Container {// Stack<Element> 的原始實現部分var items = [Element]();mutating func push(item: Element){items.append(item);}mutating func pop() -> Element{return items.removeLast();}// Container 協議的實現部分//這里占位類型參數 Element 被用作 append(_:) 方法的 item 參數和下標的返回類型。Swift 可以據此推斷出 Element 的類型即是 ItemType 的類型。因此下面的這句代碼可以不加,當然加上也沒有問題 // typealias ItemType = Element; var count: Int{return items.count;}subscript(i: Int) -> Element{return items[i];}mutating func append(item: Element){self.push(item);} }

?

?

?

轉載于:https://www.cnblogs.com/LeeGof/p/5682927.html

總結

以上是生活随笔為你收集整理的23.泛型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。