是否可以将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,我的老朋友 。