泛型總的來說有兩種使用:泛型函數(shù)、泛型類型
// 泛型函數(shù)
fun oneBasicGenericityFunction<T>(_ a: inout T, _ b: inout) {
// do something
}
// 泛型類型
struct oneBasicGenericityClass<Element> {
var items = [Element]()
}
在上面的 例子中,占位類型 T ,Element是類型參數(shù)的一個(gè)例子。類型參數(shù)指定并命名一個(gè)占位類型,并且緊隨在函數(shù)名或者類型名后面,使用一對尖括號(hào)括起來(例如 <T>,<Element>)。
擴(kuò)展泛型類型
extension oneBasicGenericityClass {
var topItem: Element? {
return items.isEmpty ? nil : items[items.count - 1]
}
func pirntElements {
for value in items.enumerated {
print(value)
}
}
}
可以看出當(dāng)你擴(kuò)展一個(gè)泛型類型的時(shí)候,你并不需要在擴(kuò)展的定義中提供類型參數(shù)列表。原始類型定義中聲明的類型參數(shù)列表在擴(kuò)展中可以直接使用,并且這些來自原始類型中的參數(shù)名稱會(huì)被用作原始定義中類型參數(shù)的引用。
類型約束
上面的oneBasicGenericityFunction(::)泛型函數(shù)和oneBasicGenericityClass泛型類型中的T,Element可以是任何類型。不過,有的時(shí)候如果能將使用在泛型函數(shù)和泛型類型中的類型添加一個(gè)特定的類型約束,將會(huì)是非常有用的。類型約束可以指定一個(gè)類型參數(shù)必須繼承自指定類,或者符合一個(gè)特定的協(xié)議或協(xié)議組合。類型參數(shù)的基本語法如下:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
// 這里是泛型函數(shù)的函數(shù)體部分
}
在Swift中,class、struct、enums都可以是用參數(shù)化類型來表達(dá)泛型的,只有在協(xié)議中需要使用associatedtype關(guān)鍵字來表達(dá)參數(shù)化類型。為什么協(xié)議不采用這樣的語法形式呢? 問題答案傳送門