22.Swift學習之泛型

泛型

  • 一個案例引發的思考
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}


var oneInt = 3
var twoInt = 4
swapTwoInts(&oneInt, &twoInt)
print(oneInt,twoInt)

如果此時我們想交換兩個Double類型、或者是其他類型的值,就需要針對不同的類型寫類似的方法,但是這些方法僅僅只是參數類型不同。如何解決?—— 泛型

//泛型函數
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}


var oneInt = 3
var twoInt = 4
swapTwoValues(&oneInt, &twoInt)
print(oneInt,twoInt)

var oneStr = "hello"
var twoStr = "world"
swapTwoValues(&oneStr, &twoStr)
print("oneStr:\(oneStr),twoStr:\(twoStr)")

var oneDouble = 10.01
var twoDouble = 20.02
swapTwoValues(&oneDouble, &twoDouble)
print("oneDouble:\(oneDouble),twoDouble:\(twoDouble)")

類型參數

類型參數指定並命名一個佔位符類型,並用<>包裹,放在函數名後面,如上面例子中的 T。可以用它來指定參數類型,或者返回值的類型。在真正調用的時候會被實際的類型替代,如傳遞的是Int,就替換爲Int,如果傳入的是Double類型就替換爲Double等等

類型約束

  • 上面的swapTwoValues(_:_:)函數可以用於任意類型。但是,有時在用於泛型函數需要遵循特定的類型。
  • 類型約束指出一個類型形式參數必須繼承自特定類,或者遵循一個特定的協議、組合協議。
  • 語法
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}

關聯類型

  • 關聯類型通過 associatedtype 關鍵字指定
  • Element 起到了佔位符的作用,指示了某種類型
  • 在實現的時候不能直接用 Element
  • Element 在遵守協議中協議方法中明確泛型的類型
protocol SomeProtocol {

    associatedtype Element
    
    func method1(element: Element)
    func method2(element: Element)
}



struct TestStruct: SomeProtocol {
    
    func method1(element: String) {
        print("method1: \(element)")
    }
    
    func method2(element: String) {
        print("method2: \(element)")
    }
}
TestStruct().method1(element: "Hello")  
TestStruct().method2(element: "World")

給關聯類型添加約束

//要遵循這個版本的 Container ,容器的 Item 必須遵循 Equatable 協議
protocol SomeProtocol {

    associatedtype Element: Equatable
    
    func method1(element: Element)
    func method2(element: Element)
}

泛型where分句

  • 泛型 where 分句能夠要求一個關聯類型必須遵循指定的協議,或者指定的類型形式參數和關聯類型必須相同
  • 泛型 where 分句以 where 關鍵字開頭
protocol SomeProtocol {
    func say()
}

struct Bird: SomeProtocol {  
    func say() {
        print("Hello")
    }
    
}

func genericFunc<T>(num: T) where T: SomeProtocol {
    print(num)
}

genericFunc(num: Bird())
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章