泛型是 Swift 最強(qiáng)大的特性之一霜第,許多 Swift 標(biāo)準(zhǔn)庫(kù)是通過(guò)泛型代碼構(gòu)建的葛家。
例如, Swift 的數(shù)組和字典都是泛型集合泌类。你可以創(chuàng)建一個(gè)存有整型值或者字符串值的數(shù)組癞谒,有必要的話,還可以創(chuàng)建一個(gè)任何 Swift 支持類型的數(shù)組。類似的弹砚,你也可以創(chuàng)建一個(gè)字典用于存儲(chǔ)任意指定類型的值双仍。
1 泛型函數(shù)
T是一個(gè)占位類型,其他字母也可以桌吃,只要在尖括號(hào)中就行殊校。
可以理解為:在定義的時(shí)候還不知道是啥類型,那就假設(shè)是T類型读存,等到調(diào)用時(shí)为流,給過(guò)來(lái)什么類型的參數(shù),那T就是上面類型让簿。
func swapValue<T>(_ a: inout T, _ b: inout T) {
let tmp = a
a = b
b = tmp
}
var a = 1
var b = 3
swapValue(&a, &b)
print(a,b)
var s1 = "word"
var s2 = "單詞"
swapValue(&s1, &s2)
print(s1, s2)
2 類型參數(shù)
T就是類型參數(shù)敬察。可以定義多個(gè)類型參數(shù)尔当。
3 命名類型參數(shù):就是把類型參數(shù)命名為一個(gè)容易閱讀的名字(大寫(xiě)字母開(kāi)頭的駝峰命名法)莲祸。
Dictionary<Key, Value>
Array<Element>
4 泛型類型
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: "uno")
stackOfStrings.push(item: "dos")
stackOfStrings.push(item: "tres")
stackOfStrings.push(item: "cuatro")
5 擴(kuò)展一個(gè)泛型類型
不需要在擴(kuò)展的定義中提供類型參數(shù)列表。原始類型定義中聲明的類型參數(shù)列表在擴(kuò)展中可以直接使用椭迎,并且這些來(lái)自原始類型中的參數(shù)名稱會(huì)被用作原始定義中類型參數(shù)的引用锐帜。
extension Stack {
var topItem: Element? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
6 類型約束:指定一個(gè)類型參數(shù)必須繼承自指定類,或者符合一個(gè)特定的協(xié)議或協(xié)議組合畜号。
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // 這里是泛型函數(shù)的函數(shù)體部分
}
func findIndex<T>(array: [T], _ valueToFind: T) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
不是所有的 Swift類型都可以用等式符(==)進(jìn)行比較缴阎。
Swift標(biāo)準(zhǔn)庫(kù)中定義了一個(gè) Equatable 協(xié)議,該協(xié)議要求任何遵循該協(xié)議的類型必須實(shí)現(xiàn)等式符( == )及不等符( != )简软。
func findIndex<T: Equatable>(array: [T], _ valueToFind: T) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
7 關(guān)聯(lián)類型
關(guān)聯(lián)類型為協(xié)議中的 某個(gè)類型提供了一個(gè)占位名(或者說(shuō)別名)蛮拔,其代表的實(shí)際類型在協(xié)議被采納時(shí)才會(huì)被指定。
protocol Container {
associatedtype ItemType
mutating func append(item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
struct Stack2<Element>: Container {
// Stack<Element> 的原始實(shí)現(xiàn)部分
var items = [Element]()
mutating func push(item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
// Container 協(xié)議的實(shí)現(xiàn)部分
mutating func append(item: Element) {
self.push(item: item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element { // swift 可以推斷出ItemType就是Element
return items[i]
}
}
playground文件在andyRon/LearnSwift