Swift中協議與泛型的應用
阿新 • • 發佈:2018-12-04
1.方法的泛型
//泛型約束(冒號後邊跟class或者協議,傳入的引數someT和someU必須是遵循該協議或類---(NAArray類,Comparable協議))
func someFunction<T:NSArray, U:Comparable>(someT: T, someU: U) {
// 這裡是泛型函式的函式體部分
}
func comparTwo<T:Comparable>( _ a:T,_ b:T) -> Bool {
return a>b
}
與OC中的id有點類似,只是可以遵循協議或者指定型別
2.struct的泛型
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>() print("字串元素入棧: ") stackOfStrings.push("google") stackOfStrings.push("runoob") print(stackOfStrings.items); let deletetos = stackOfStrings.pop() print("出棧元素: " + deletetos) var stackOfInts = Stack<Int>() print("整數元素入棧: ") stackOfInts.push(1) stackOfInts.push(2) print(stackOfInts.items);
(1)struct也可以使用泛型,當呼叫結構體的時候可以指定泛型的具體型別
//協議 protocol Container { //associatedtype 關鍵字來指定關聯型別(就是定義一個泛型名字叫ItemType,這個等價於下邊的Element,都是一個泛型) associatedtype ItemType //新增一個新元素到容器裡 mutating func append(item:ItemType) //獲取容器中元素的數 var count: Int{get} //通過索引值型別為 Int 的下標檢索到容器中的每一個元素 //下標指令碼是系統提供的可以對struct或者enum或者陣列等重寫的一個屬性 subscript(i:Int) -> ItemType {get} //不一定是一維的,也可以是二維的 // subscript(row: Int, col: Int) -> Double { // get // } } //Stack 遵循Container協議, (Element可以設定遵循某個協議)(這個協議可以寫在extension中的where裡) struct Stack<Element>:Container { var items = [Element]() mutating func push(item:Element){ items.append(item) } mutating func pop(item:Element){ items.removeLast() } //協議部分 mutating func append(item: Element) { self.push(item: item) } var count: Int{ return items.count } subscript(i: Int) ->Element{ return items[i] } } //where是對Stack傳入的元素的型別約束,必須遵循可以進行等於比較的協議(傳入陣列就不行),其實也可以在Stack定義的時候讓元素遵循某個協議,這個協議的範圍只是在呼叫這個擴充套件方法裡,上邊的push元素不遵循 extension Stack where Element:Equatable{ func isTop(item:Element) -> Bool { guard let topItem = items.last else { return false } return topItem == item } }
(2)呼叫Stack
func one(){
var bbb = Stack<String>()
bbb.push(item:"google")
bbb.push(item:"runoob")
bbb.push(item:"taobao")
let mm = bbb.isTop(item: "optional")
print("istop==\(mm)")
//元素列表
print(bbb.items)
print(bbb.count)
var aaa = Stack<String>()
aaa.push(item:"google")
aaa.push(item:"runoob")
aaa.push(item:"taobao")
}
(3)寫一個泛型遵循Container協議的方法,正好上述Stack遵循Container協議,可以把aaa和bbb作為引數傳進去
func allItemsMatch<C1:Container,C2:Container>(containter1:C1,containter2:C2) -> Bool
where C1.ItemType == C2.ItemType, C1.ItemType:Equatable
{
if containter1.count != containter2.count {
return false
}
for i in 0..<containter1.count {
if containter1[i] != containter2[i]{
return false
}
}
return true
}
呼叫方法
if allItemsMatch(containter1: aaa, containter2: bbb) {
print("aaa == bbb")
}else{
print("aaa != bbb")
}
補充:
subscript是系統提供的,通常情況下,我們在使用陣列(Array)或字典(Dictionary)時會使用到下標。其實在Swift中,我們還可以給類、結構、列舉等自定義下標(subscript)。
subscript例子:https://blog.csdn.net/sinat_27706697/article/details/47122137
整合的程式碼加自己的理解,參考文章:http://www.runoob.com/swift/swift-generics.html