是否可以将types约束添加到Swift协议一致性扩展?

我想扩展Array添加符合一个新的协议 – 但只适用于其元素本身符合特定协议的数组。

更一般地说,我希望只有当types参数符合一定的约束条件时,带有types参数的types(不pipe是协议还是具体types)才能实现协议。

从Swift 2.0开始,这似乎是不可能的。 有没有我失踪的方法?

假设我们有Friendly协议:

 protocol Friendly { func sayHi() } 

我们可以扩展现有的types来实现它:

 extension String: Friendly { func sayHi() { print("Greetings from \(self)!") } } "Sally".sayHi() 

当元素全部Friendly时,我们也可以扩展Array来实现sayHi()

 extension Array where Element: Friendly { func sayHi() { for elem in self { elem.sayHi() } } } ["Sally", "Fred"].sayHi() 

此时, [Friendly]types应该自己实现Friendly ,因为它符合协议的要求。 但是,这段代码不能编译:

 extension Array: Friendly where Element: Friendly { func sayHi() { for elem in self { elem.sayHi() } } } 

错误消息是“带有约束的types'数组的扩展'不能有一个inheritance子句,”这似乎直接closures了门的方法。

有没有间接的解决方法? 我可以使用一些聪明的技巧? 也许有一种方法涉及到扩展SequenceType而不是Array

一个工作解决scheme将使这个代码编译:

 let friendly: Friendly = ["Foo", "Bar"] 

这在Swift中是不可能的(从Xcode 7.1开始)。 如错误所示,您不能将协议一致性(“inheritance子句”)限制为types受限的扩展。 也许有一天。 我不相信这是不可能的,但现在还没有实施。

你可以得到最接近的是创build一个包装types,如:

 struct FriendlyArray<Element: Friendly>: Friendly { let array: [Element] init(_ array: [Element]) { self.array = array } func sayHi() { for elem in array { elem.sayHi() } } } let friendly: Friendly = FriendlyArray(["Foo", "Bar"]) 

(您可能希望将FriendlyArray扩展为CollectionType 。)

想了解一下我试图做这个工作的疯狂的故事,以及我从边缘爬回来,看到NSData,我的老朋友 。