是否可以在Swift中创建一个仅限于一个类的Array扩展?

Dou*_*ith 7 arrays swift ios8

我可以创建一个适用于例如字符串的数组扩展吗?

Mar*_*n R 13

从Swift 2开始,现在可以通过协议扩展来实现,协议扩展为符合类型提供方法和属性实现(可选择受其他约束限制).

一个简单的例子:为所有符合SequenceType(例如Array)序列元素的类型定义一个方法String:

extension SequenceType where Generator.Element == String {
    func joined() -> String {
        return "".join(self)
    }
}

let a = ["foo", "bar"].joined()
print(a) // foobar
Run Code Online (Sandbox Code Playgroud)

扩展方法不能直接定义struct Array,但仅适用于符合某些协议的所有类型(带有可选约束).因此,必须找到Array符合的协议,并提供所有必要的方法.在上面的例子中,就是这样SequenceType.

另一个例子(如何在Swift中将正确位置的元素插入到排序数组中的变体?):

extension CollectionType where Generator.Element : Comparable, Index : RandomAccessIndexType {
    typealias T = Generator.Element
    func insertionIndexOf(elem: T) -> Index {
        var lo = self.startIndex
        var hi = self.endIndex
        while lo != hi {
            // mid = lo + (hi - 1 - lo)/2
            let mid = lo.advancedBy(lo.distanceTo(hi.predecessor())/2)
            if self[mid] < elem {
                lo = mid + 1
            } else if elem < self[mid] {
                hi = mid
            } else {
                return mid // found at position `mid`
            }
        }
        return lo // not found, would be inserted at position `lo`
    }
}

let ar = [1, 3, 5, 7]
let pos = ar.insertionIndexOf(6)
print(pos) // 3
Run Code Online (Sandbox Code Playgroud)

这里的方法被定义为扩展,CollectionType因为需要对元素进行下标访问,并且元素是必需的Comparable.


Rob*_*ier 5

更新:请参阅下面的Martin对Swift 2.0更新的回答.(我不能删除这个答案,因为它被接受;如果Doug能接受Martin的回答,我会删除这个,以避免将来混淆.)


这在论坛中已经出现过几次了,答案是否定的,你今天不能这样做,但他们认为这是一个问题,他们希望将来能够改进这个问题.他们想要添加到stdlib的东西也需要这个.这就是stdlib有这么多免费功能的原因.对于这个问题或"无默认实现"问题(即"特征"或"混合"),大多数都是解决方法.

  • 谢谢,这似乎是一个奇怪的遗漏.会保持我的手指交叉. (2认同)