Swift基础学习<二十>:泛型-泛型协议

深渊向深渊呼唤

泛型协议: 除了节点式声明泛型外,还有其他方式声明一个泛型,比如使用关键字associatedtype(Swift 2.2版本之前是 typealias关键字) : protocol SomeProtocol { associated type Element func elementMethod1 (element:Element) func elementMethod2 (element:Element) } 这里虽然没有出现节点语法,但是上面的协议却是个不折不扣的泛型协议,Element起到了占位符的作用,指示了某种类型。根据协议的规则,协议SomeProtocol的遵守者必须实现上面两个方法,此时 Element 除了显式地体现了泛型的优势外,还隐性地约束了两个方法的参数必须是相同类型的。由于关联类型本身是泛型的,所以你可以像约束其他泛型那样约束关联类型: associated type OwnElement:Comparable 不用刻意指定 Element的具体类型,编译器会根据实现方法时传入的参数类型确定 Element 的具体类型,比如:

struct TestStruct:SomeProtocol {
	func elementMethod1 (element:String) {
		print(“elementFromMethod1:\(element)”)
	}
	func elementMethod2 (element:String) {
		print (“elementFromMethod2:\(element)”)
	}
}

注意,在实现的时候不能直接用 Element, Element 只存在于具体实现之前,如果你尝试使用 Element, 那么编译器会报错。在TestStruct 中,由于传入了 String,所以泛型Element的实际值就是 String,如果你尝试让两个方法的参数类型不同,那么编译器同样会报错。 类似于的 associatedtype的还有self关键字,代表了协议遵守者本身的类型,适用于比较这类方法,其必须传入另一个想同类型的参数才有意义,定义一个self类型的方法示例如下: protocol CanCompare { func isBigger(other:Self) -> Bool }

然后使用我们之前定义的盒子类型来试验一下:

struct BoxInt:CanCompare { var intValue:Int func isBigger(other:BoxInx) -> Bool { return self.intValue > other.intValue } }

编译通过,现在新建两个实例测试一下: BoxInt(intValue:3).isBigger(BoxInt(intValue:2)) //结果为 true.

没看明白。。。后面使用再总结吧,感觉脑子不够用了。学习效率低了。

栏目