about 6 years ago

泛型設計主要是可以讓型別一直到實體使用的時候再決定,而不用一開始就宣告,
這樣的方式可以能讓程式碼變得更有彈性也更容易重複利用。

泛型函式

下述是傳統來設計替換兩個變數的函式

func swapTwo(_ a: inout Int, _ b: inout Int) {
    let temp = a
    a = b
    b = temp
}

使用泛型的目的在於,此函式的參數不再侷限於 Int。

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

T 代表的是型別參數,可隨意命名。

泛型類別

可以在 classes, structures 或是 enumerations 宣告泛型類別,並且在建立實體時宣告類別。

class MyClass<T> {
    var pro: T?
    func myFunc() -> T? {
        return pro
    }
}
let c = MyClass<Int>()

extension 可以使用泛型類別。

class MyClass<T> {
    var pro: T?
}
extension MyClass {
    var getPro: T {
        return pro
    }
}

泛型類別限制

某些情況下函式會需要限制參數類別,比如說屬於某個 class 或是 protocol 類別。

class MyClass {
}
protocol MyProtocol {
}
func MyFunc<T: MyClass, E: MyProtocol> (c: T, p: E) {
}

有某些關鍵字可以來代表屬於哪種限制。

func MyFunc<R: Equatable>(para: R, para2: R) {
    if para == para2 {
    }
}

關聯類別

在 protocol 內先定義某個泛型類別,再由實作對象來決定真正類別,關鍵字為 associatedtype。

protocol MyProtocol {
    associatedtype newType
    var pro: newType { get }
}
class MyClass: MyProtocol {
    typealias newType = Int
    var pro: Int {
        get {
            return 1
        }
    }
}

限制子句

加上 where 針對此泛型做額外限制。

class MyClass<T> where T: Equatable {
}

若將 protocol 當作 type 做傳遞時,此 protocol 內有 associated type,
也可以使用 where 來針對此泛型做限制。

protocol MyProtocol {
    associatedtype newType
}
func myFunc<T: MyProtocol> (_ para: T) -> Void where T.newType: Equatable {
}

可以在 extension 再加上 where 限制,extension 的 function 必須要滿足限制才能使用。

class MyClass<T> {
    func(para: T) {
    }
}
extension MyClass where T: Equatable {
    func(para: T, para: String) {
    }
}
← iOS Swift : Protocols iOS Swift : Access Control →