我想扩展Array
,为一个新协议添加一致性——但仅适用于元素本身符合特定协议的array.
更一般地说,我希望具有类型参数的类型(无论是协议还是具体类型)只在类型参数匹配某些约束时实现协议.
从Swift 2.0开始,这似乎是不可能的.有什么我错过的吗?
实例
假设我们有Friendly
个协议:
protocol Friendly {
func sayHi()
}
我们可以扩展现有类型来实现它:
extension String: Friendly {
func sayHi() {
print("Greetings from \(self)!")
}
}
"Sally".sayHi()
当Array
的元素都是Friendly
时,我们还可以将其扩展为sayHi()
:
extension Array where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}
["Sally", "Fred"].sayHi()
此时,类型[Friendly]
本身应该实现Friendly
,因为它满足协议的要求但是,此代码不编译:
extension Array: Friendly where Element: Friendly {
func sayHi() {
for elem in self {
elem.sayHi()
}
}
}
错误消息是"带有约束的'Array'类型的扩展不能有继承子句",这似乎彻底关闭了直接方法的大门罢工>
是否有间接的解决方法?我能用些聪明的把戏吗?也许有一种方法需要将SequenceType
而不是Array
扩展罢工>
一个可行的解决方案将使这段代码得以编译:
let friendly: Friendly = ["Foo", "Bar"]
Update:这已经登陆Swift 4.1,这是一件美丽的事情!
现在,extension Array: Friendly where Element: Friendly
个示例按照原始问题中给出的方式编译.