a亚洲精品_精品国产91乱码一区二区三区_亚洲精品在线免费观看视频_欧美日韩亚洲国产综合_久久久久久久久久久成人_在线区

首頁 > 編程 > C > 正文

Swift編程中的泛型解析

2020-01-26 14:50:02
字體:
來源:轉載
供稿:網友

泛型代碼可以讓你寫出根據自我需求定義、適用于任何類型的,靈活且可重用的函數和類型。它可以讓你避免重復的代碼,用一種清晰和抽象的方式來表達代碼的意圖。
 
泛型是 Swift 強大特征中的其中一個,許多 Swift 標準庫是通過泛型代碼構建出來的。事實上,泛型的使用貫穿了整本語言手冊,只是你沒有發現而已。例如,Swift 的數組和字典類型都是泛型集。你可以創建一個Int數組,也可創建一個String數組,或者甚至于可以是任何其他 Swift 的類型數據數組。同樣的,你也可以創建存儲任何指定類型的字典(dictionary),而且這些類型可以是沒有限制的。
 
泛型所解決的問題
這里是一個標準的,非泛型函數swapTwoInts,用來交換兩個Int值:

復制代碼 代碼如下:

func swapTwoInts(inout a: Int, inout b: Int)
    let temporaryA = a
    a = b
    b = temporaryA
}

這個函數使用寫入讀出(in-out)參數來交換a和b的值,請參考寫入讀出參數。
 
swapTwoInts函數可以交換b的原始值到a,也可以交換a的原始值到b,你可以調用這個函數交換兩個Int變量值:
復制代碼 代碼如下:

var someInt = 3
var anotherInt = 107
swapTwoInts(&someInt, &anotherInt)
println("someInt is now /(someInt), and anotherInt is now /(anotherInt)")
// 輸出 "someInt is now 107, and anotherInt is now 3"
swapTwoInts函數是非常有用的,但是它只能交換Int值,如果你想要交換兩個String或者Double,就不得不寫更多的函數,如 swapTwoStrings和swapTwoDoublesfunctions,如同如下所示:
func swapTwoStrings(inout a: String, inout b: String) {
    let temporaryA = a
    a = b
    b = temporaryA
}
 
func swapTwoDoubles(inout a: Double, inout b: Double) {
    let temporaryA = a
    a = b
    b = temporaryA
}

你可能注意到 swapTwoInts、 swapTwoStrings和swapTwoDoubles函數功能都是相同的,唯一不同之處就在于傳入的變量類型不同,分別是Int、String和Double。
 
但實際應用中通常需要一個用處更強大并且盡可能的考慮到更多的靈活性單個函數,可以用來交換兩個任何類型值,很幸運的是,泛型代碼幫你解決了這種問題。(一個這種泛型函數后面已經定義好了。)
 
注意: 在所有三個函數中,a和b的類型是一樣的。如果a和b不是相同的類型,那它們倆就不能互換值。Swift 是類型安全的語言,所以它不允許一個String類型的變量和一個Double類型的變量互相交換值。如果一定要做,Swift 將報編譯錯誤。

泛型函數:類型參數
泛型函數可以訪問任何數據類型,如:'Int' 或 'String'.

復制代碼 代碼如下:

func exchange<T>(inout a: T, inout b: T) {
   let temp = a
   a = b
   b = temp
}

var numb1 = 100
var numb2 = 200

println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")

var str1 = "Generics"
var str2 = "Functions"

println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")


當我們使用 playground 運行上面的程序,得到以下結果

Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics

函數 exchange()用于交換其在上述方案中描述和<T>被用作類型參數值。這是第一次,函數 exchange()被調用返回Int值,第二次調用函數 exchange()將返回String值。多參數類型可包括用逗號分隔在尖括號內。

類型參數被命名為用戶定義來了解擁有類型參數的目的。 Swift 提供<T>作為泛型類型參數的名字。 但是型像數組和字典參數也可以命名為鍵,值,以確定它們輸入屬于“字典”。

泛型類型

復制代碼 代碼如下:

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
  
   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push("Swift")
println(tos.items)

tos.push("Generics")
println(tos.items)

tos.push("Type Parameters")
println(tos.items)

tos.push("Naming Type Parameters")
println(tos.items)


let deletetos = tos.pop()


當我們使用 playground 運行上面的程序,得到以下結果

[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]

擴展泛型類型
擴展堆棧屬性要知道該項目的頂部包含在“extension” 關鍵字。

復制代碼 代碼如下:

struct TOS<T> {
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }

   mutating func pop() -> T {
      return items.removeLast()
   }
}

var tos = TOS<String>()
tos.push("Swift")
println(tos.items)

tos.push("Generics")
println(tos.items)

tos.push("Type Parameters")
println(tos.items)

tos.push("Naming Type Parameters")
println(tos.items)

extension TOS {
   var first: T? {
      return items.isEmpty ? nil : items[items.count - 1]
   }
}

if let first = tos.first {
   println("The top item on the stack is /(first).")
}


當我們使用 playground 運行上面的程序,得到以下結果

[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]

在堆棧頂部的項目命名類型參數。

類型約束
Swift 語言允許“類型約束”指定類型參數是否從一個特定的類繼承,或者確保協議一致性標準。

復制代碼 代碼如下:

func exchange<T>(inout a: T, inout b: T) {
   let temp = a
   a = b
   b = temp
}

var numb1 = 100
var numb2 = 200

println("Before Swapping Int values are: /(numb1) and /(numb2)")
exchange(&numb1, &numb2)
println("After Swapping Int values are: /(numb1) and /(numb2)")

  
var str1 = "Generics"
var str2 = "Functions"

println("Before Swapping String values are: /(str1) and /(str2)")
exchange(&str1, &str2)
println("After Swapping String values are: /(str1) and /(str2)")


當我們使用 playground 運行上面的程序,得到以下結果

Before Swapping Int values are: 100 and 200After Swapping Int values are: 200 and 100Before Swapping String values are: Generics and FunctionsAfter Swapping String values are: Functions and Generics

關聯類型
Swift 允許相關類型,并可由關鍵字“typealias”協議定義內部聲明。

復制代碼 代碼如下:

protocol Container {
   typealias ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}

struct TOS<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }
  
   mutating func pop() -> T {
      return items.removeLast()
   }

   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item)
   }
  
   var count: Int {
      return items.count
   }

   subscript(i: Int) -> T {
      return items[i]
   }
}

var tos = TOS<String>()
tos.push("Swift")
println(tos.items)

tos.push("Generics")
println(tos.items)

tos.push("Type Parameters")
println(tos.items)

tos.push("Naming Type Parameters")
println(tos.items)


當我們使用 playground 運行上面的程序,得到以下結果

[Swift][Swift, Generics][Swift, Generics, Type Parameters][Swift, Generics, Type Parameters, Naming Type Parameters]

Where 子句
類型約束使用戶能夠定義與泛型函數或類型相關聯的類型的參數要求。用于定義相關類型的 'where' 子句聲明為類型參數列表的一部分要求。 “where”關鍵字類型參數后面類型和相關類型之間的相關類型的限制,平等關系的列表后放置。

復制代碼 代碼如下:

 protocol Container {
   typealias ItemType
   mutating func append(item: ItemType)
   var count: Int { get }
   subscript(i: Int) -> ItemType { get }
}

struct Stack<T>: Container {
   // original Stack<T> implementation
   var items = [T]()
   mutating func push(item: T) {
      items.append(item)
   }

   mutating func pop() -> T {
      return items.removeLast()
   }

   // conformance to the Container protocol
   mutating func append(item: T) {
      self.push(item)
   }
  
   var count: Int {
      return items.count
   }

   subscript(i: Int) -> T {
      return items[i]
   }
}

func allItemsMatch<
   C1: Container, C2: Container
   where C1.ItemType == C2.ItemType, C1.ItemType: Equatable>
   (someContainer: C1, anotherContainer: C2) -> Bool {
   // check that both containers contain the same number of items
   if someContainer.count != anotherContainer.count {
      return false
}

// check each pair of items to see if they are equivalent
for i in 0..<someContainer.count {
   if someContainer[i] != anotherContainer[i] {
      return false
   }
}
      // all items match, so return true
      return true
}

var tos = Stack<String>()
tos.push("Swift")
println(tos.items)

tos.push("Generics")
println(tos.items)

tos.push("Where Clause")
println(tos.items)

var eos = ["Swift", "Generics", "Where Clause"]
println(eos)


當我們使用 playground 運行上面的程序,得到以下結果

[Swift][Swift, Generics][Swift, Generics, Where Clause][Swift, Generics, Where Clause]

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 欧美黄色片 | 一区二区不卡视频在线观看 | 在线天堂中文在线资源网 | 成人a在线视频免费观看 | 精品欧美乱码久久久久久 | 日韩一级视频 | 成人精品鲁一区一区二区 | 自拍偷拍小视频 | av在线一区二区 | 国产精品视频黄色 | 久久密| 中文字幕一区二区三区四区不卡 | 免费观看性欧美大片无片 | 韩国三级中文字幕hd久久精品 | 国产精品一区二区三区四区在线观看 | 日日天天 | 亚洲国产精品18久久 | 久久国产精品视频 | 日韩高清中文字幕 | 国产一级片 | 欧美日韩综合精品 | 国产精品成人一区二区 | 一区二区免费在线播放 | 99re热精品视频 | 亚洲一区二区三区 | 欧美久久久精品 | 国产精品一二三区 | 日韩国产精品一区二区三区 | 亚洲男人天堂网 | 成人日韩视频 | 青青草视频网 | 噜噜噜噜狠狠狠7777视频 | 不用播放器的免费av | 亚洲成a人v欧美综合天堂麻豆 | 国产第六页 | 精品久久久久久久久久久久久久 | 成人一区二区三区视频 | 国产精品久久久久久久久久久久久 | 黄色片视频免费 | 日韩久久久久久 | 午夜国产一级 |