再次解释一下协议的意义:定义某个功能模块的最小粒度,因为Swift是单继承,而无论是值类型还是引用类型都可以遵守多个协议,因此协议是比父类的粒度还要小的功能模块。协议的功能定义一定要具体并且严格,someObject:Protocol where …中where子句的匹配条件只能针对someObject的类型或者遵守的其他协议,以及Protocol中的associatedType的约束,也就是说不能根据someObject中的成员判断是否遵守该协议。举例如下:
Swift标准库中的很多基础类型都遵守了Equatable协议,这个协议要求用户定义一个==方法,这表明虽然每个类型判断是否相等的标准不同,但是在任何情况下两个遵守了Equatable协议的相同类型都可以判等,这是协议为我们所做的工作。考虑我们常用的数组,Array中也可以使用==运算,但是Array并没有遵守Equatable协议,这是因为调用Array实例的==方法的时候编译器会做限制,只有Array中所保存的元素遵守了Equatable协议的时候,Array才能进行判等,所以Array不是在任何条件下都能进行判等的,不符合Equatable协议的功能描述。这种情况下我们需要直接定义一个方法:
func ==<T: Equatable>(lhs: [T], rhs: [T]) -> Bool {
//对比las和rhs中的元素是否相等
}
方法的好处是你可以引用任意的泛型作为占位符来描述功能呢,比如这里的T,这样就可以规范两个参数必须是相同类型的数组,并且元素遵守Equatable。当Array中的元素不遵守Equatable时,在编译期调用==就会收到编译器错误。
而在使用协议的时候,someObject:Protocol where …这里的where只能对协议中声明的associatedType进行约束,而不能引入向T这样额外的占位符来描述约束。