通过遵循Swift 2中的协议来扩展类型数组

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专家都知道该怎么做?

R M*_*nke 5

您不能对一致性应用很多逻辑。它要么符合,要么不符合。但是,您可以对扩展应用一些逻辑。下面的代码使设置一致性的特定实现变得容易。这是重要的部分。

以后将其用作类型约束。

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)


Pet*_*ter 5

在更新的 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,但我添加了这个以供参考)