Jam*_* Hu 4 generics swift swift-extensions swift2
我想扩展一个类型化数组Array<SomeType>,使其符合协议SomeProtocol。现在我知道您可以扩展如下的类型化数组:
extension Array where Element: SomeType { ... }
Run Code Online (Sandbox Code Playgroud)
您还可以扩展对象以遵循以下协议:
extension Array: SomeProtocol { ... }
Run Code Online (Sandbox Code Playgroud)
但是我无法弄清楚什么是使类型化数组符合协议的正确语法,例如:
extension (Array where Element: SomeType): SomeProtocol { ... }
Run Code Online (Sandbox Code Playgroud)
任何Swift 2专家都知道该怎么做?
您不能对一致性应用很多逻辑。它要么符合,要么不符合。但是,您可以对扩展应用一些逻辑。下面的代码使设置一致性的特定实现变得容易。这是重要的部分。
以后将其用作类型约束。
class SomeType { }
Run Code Online (Sandbox Code Playgroud)
这是你的协议
protocol SomeProtocol {
func foo()
}
Run Code Online (Sandbox Code Playgroud)
这是协议的扩展。实施foo()中的扩展SomeProtocol创建一个默认。
extension SomeProtocol {
func foo() {
print("general")
}
}
Run Code Online (Sandbox Code Playgroud)
现在Array符合SomeProtocol使用的默认实现foo()。现在,所有数组都将foo()作为一种方法,这不是超级优雅。但是它什么也没做,所以不会伤害任何人。
extension Array : SomeProtocol {}
Run Code Online (Sandbox Code Playgroud)
现在很酷的东西:如果我们创建一个Array具有类型约束的扩展,Element我们可以覆盖的默认实现foo()
extension Array where Element : SomeType {
func foo() {
print("specific")
}
}
Run Code Online (Sandbox Code Playgroud)
测试:
let arrayOfInt = [1,2,3]
arrayOfInt.foo() // prints "general"
let arrayOfSome = [SomeType()]
arrayOfSome.foo() // prints "specific"
Run Code Online (Sandbox Code Playgroud)
在更新的 Swift 版本中,可以这样写:
extension Array: SomeProtocol where Element == SomeType { ... }
不确定这在哪个 Swift 版本中成为可能,但以下在 Swift 4.1 中有效
class SomeType { }
protocol SomeProtocol {
func foo()
}
extension Array: SomeProtocol where Element == SomeType {
func foo() {
print("foo")
}
}
let arrayOfSome = [SomeType()]
arrayOfSome.foo() // prints "foo"
let arrayOfInt = [1,2,3]
arrayOfInt.foo() // Will not compile: '[Int]' is not convertible to 'Array<SomeType>'
Run Code Online (Sandbox Code Playgroud)
(我知道这个问题特别要求 Swift 2,但我添加了这个以供参考)