Swift中协议与泛型的应用

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

猜你喜欢

转载自blog.csdn.net/HuberCui/article/details/83660143