Swift學習_泛型

Swift

泛型
泛型的本質(zhì)是參數(shù)化類型,也就是說所有操作的數(shù)據(jù)類型被制定為一個參數(shù),這種參數(shù)類型可以用在類型、函數(shù)和方法中。

1.泛型函數(shù)

泛型可以用于函數(shù)的參數(shù)和返回值等,使用了泛型的函數(shù)通常稱為泛型函數(shù)。下面看3個普通函數(shù)
// 1.1關(guān)于Int類型的交換函數(shù)
func exchangeInt(a:inout Int,b:inout Int){
    let temp = a
    a = b
    b = temp
}

var numb1 = 100
var numb2 = 200
print("交換前 numb1 = \(numb1) and numb2 = \(numb2)")
exchangeInt(a: &numb1, b: &numb2)
print("交換后 numb1 = \(numb1) and numb2 = \(numb2)")

// inout在寫法上與C語言傳遞地址的寫法十分類似,在調(diào)用函數(shù)傳入?yún)?shù)是帶有前綴&,就好像取地址傳進去了一樣,實則不然。


// 1.2關(guān)于Double類型的交換函數(shù)
func exchangeDouble(a:inout Double,b:inout Double){
    let temp = a
    a = b
    b = temp
}

var numbA = 30.5
var numbB = 107.77
print("交換前 numb1 = \(numbA) and numb2 = \(numbB)")
exchangeDouble(a: &numbA, b: &numbB)
print("交換后 numb1 = \(numbA) and numb2 = \(numbB)")


// 1.3關(guān)于String類型的交換函數(shù)
func exchangeString(a:inout String,b:inout String){
    let temp = a
    a = b
    b = temp
}

var strA = "Harry"
var strB = "Sun"
print("交換前 numb1 = \(strA) and numb2 = \(strB)")
exchangeString(a: &strA, b: &strB)
print("交換后 numb1 = \(strA) and numb2 = \(strB)")

inout在寫法上與C語言傳遞地址的寫法十分類似,在調(diào)用函數(shù)傳入?yún)?shù)是帶有前綴&,就好像取地址傳進去了一樣,實則不然。

上 面這三個函數(shù)實現(xiàn)都是相同的,唯一不同的是傳入的參數(shù)類型不同,這樣顯得代碼比較冗余,所以我們使用泛型函數(shù)
func exchange<T>(a:inout T,b:inout T){
    let temp = a
    a = b
    b = temp
}
// 這樣對于任何類型都是可以的
numb1 = 100
numb2 = 200
print("交換之前 numb1 = \(numb1) and numb2 = \(numb2)")
exchange(a: &numb1,b: &numb2)
print("交換之后 numb1 = \(numb1) and numb2 = \(numb2)")
numbA = 30.5
numbB = 107.77
print("交換之前 numb1 = \(numbA) and numb2 = \(numbB)")
exchange(a: &numbA,b: &numbB)
print("交換之后 numb1 = \(numbA) and numb2 = \(numbB)")

strA = "Harry"
strB = "Sun"
print("交換之前 numb1 = \(strA) and numb2 = \(strB)")
exchange(a: &strA,b: &strB)
print("交換之后 numb1 = \(strA) and numb2 = \(strB)")

2.泛型類型

swift不但允許定義泛型函數(shù),而且還允許定義泛型類型。這些自定義泛型類型可以是類、結(jié)構(gòu)體和枚舉,能適用于任何類型,如同A仍然有何Dictionary的用法一樣
// 先定義一個普通類型的棧
struct IntStack {
    var items = [Int]()
    mutating func push(item:Int){
        items.append(item)
    }
    mutating func po() -> Int{
        return items.removeLast()
    }
    
}

// 再定義一個泛型類型的棧,從泛型的棧中可以看出泛型類型
struct Stack<Element> {
    var items = [Element]()
    
    mutating func push(item:Element){
        items.append(item)
    }
    mutating func pop() -> Element{
        return items.removeLast()
    }
}

var stackOfStrings = Stack<String>()
stackOfStrings.push(item: "A")
stackOfStrings.push(item: "B")
stackOfStrings.push(item: "C")
stackOfStrings.push(item: "D")

let fromTheTop = stackOfStrings.pop()
print("fromTheTop的值是\(fromTheTop)")

// 擴展泛型棧
extension Stack{
    var topItem:Element?{
        return items.isEmpty ? nil : items[items.count - 1]
    }
}

if let topItem = stackOfStrings.topItem{
    print("棧頂?shù)脑厥荺(topItem)")
}

3.類型約束

默認情況下,泛型函數(shù)和泛型類型可作用于任何類型,不過,有時候需要對泛型函數(shù)和泛型類型中的類型做一些強制約束,例如,swift的Dictionary類型對字典的鍵類型做出約束,要求鍵類型是可哈希的,下面舉一個例子更好的理解類型約束
func findStringIndex(array:[String],valueToFind:String) -> Int?{
    for(index,value) in array.enumerated(){
        if value == valueToFind {
            return index
        }
    }
    return nil
}
let strings = ["Beijing","Shanghai","Guangzhou","Shangdong","Zhengzhou"]
if let foundIndex = findStringIndex(array: strings, valueToFind: "Shanghai"){
    print("Shanghai在數(shù)組中的位置是\(foundIndex)")
}

// findStringIndex這個函數(shù)只能查找字符串在數(shù)組中的索引,用處不是很大,下面寫出相同功能的泛型函數(shù)findIndex(_,_)用占位類型T替換String
func findIndex<T:Equatable>(array:[T],valueToFind:T) -> Int? {
    for (index,Value) in array.enumerated() {
        if(Value == valueToFind){
            return index
        }
    }
    return nil
}

// 這里我們使用了Equatable協(xié)議作為限定,在swift標準庫中定義了一個Equatable協(xié)議,該協(xié)議要求其遵守者必須實現(xiàn)等式符(==),從而能使用==對符合該協(xié)議的類型值進行比較,因為很多類型和自定義的類型都沒有遵守該協(xié)議
let doubleIndex = findIndex(array:[3.14159,0.1,0.25], valueToFind: 9.3)
print("9.3在數(shù)組中的位置是\(String(describing: doubleIndex))")


let stringIndex = findIndex(array: ["ios","android","h5"], valueToFind: "ios")
print("ios在數(shù)組中的位置是\(String(describing: stringIndex))")

代碼已上傳至git:
--> 傳送門:Swift_基本語法

附錄

查看完整專欄《Swift學習》

有問題歡迎指正以及相互探討 —— CoderSun

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容

  • 泛型的概念 泛型代碼可根據(jù)自定義需求,寫出適用于任何類型、靈活且可重用的函數(shù)和類型,避免重復的代碼,用一種清晰和抽...
    伯wen閱讀 408評論 0 2
  • 本章將會介紹 泛型所解決的問題泛型函數(shù)類型參數(shù)命名類型參數(shù)泛型類型擴展一個泛型類型類型約束關(guān)聯(lián)類型泛型 Where...
    寒橋閱讀 649評論 0 2
  • 泛型代碼可以確保你寫出靈活的,可重用的函數(shù)和定義出任何你所確定好的需求的類型。你的可以寫出避免重復的代碼,并且用一...
    iOS_Developer閱讀 813評論 0 0
  • 泛型(Generics) 泛型代碼允許你定義適用于任何類型的,符合你設(shè)置的要求的,靈活且可重用的 函數(shù)和類型。泛型...
    果啤閱讀 693評論 0 0
  • 第一次從另一個意思理解“位”這個字,還是在荊門的時候,清晨和朋友一起去過早,路上朋友說起一些瑣碎小事時提及。當時朋...
    楊云yangyun閱讀 553評論 0 2