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) {
}
}