在 Swift 2 中扩展 CollectionType

Extending CollectionType in Swift 2

所以我正在尝试扩展 Swift 2

中的 CollectionType 协议
protocol CollectionAccess: CollectionType {
    func getElement<T: Hashable>(key: T) -> Self.Generator.Element?
}

extension Dictionary : CollectionAccess {
    func getElement(key: Key) -> Dictionary.Element? {
        if let value = self[key] {
            return (key, value)
        }
        return nil
    }
}

编译时会抛出一个错误:

error: type 'Dictionary' does not conform to protocol 'CollectionAccess' extension Dictionary : CollectionAccess

函数 getElement(...) 编译良好,作为 Dictionary 的 n 扩展本身工作正常但不是

extension Dictionary : CollectionAccess

=====进度======================

我通过更改我在词典扩展中的签名设法摆脱了错误:

extension Dictionary : CollectionAccess {
    func getElement<K: Hashable where K == Dictionary.Key>(key: K) -> Dictionary.Generator.Element? {
        self[key]

现在的问题是:

error: cannot subscript a value of type 'Dictionary' with an index of type 'K' self[key]

我要做的是设置签名以表明 K 与 Dictionary.Key 类型是相同的 Hashable。

'Key' 和 'Value' 是 Dictionary 中的占位符,因此您无法在 CollectionType 协议扩展的方法签名中访问它们 - 因此要使其正常工作,您必须进行强制转换.

我觉得有点不对劲,但我认为你可以让它与这样的东西一起工作:

extension Dictionary : CollectionAccess {
    func getElement<T : Hashable>(key: T) -> Dictionary.Generator.Element?     {
        if key.self is Key.Type {
            let tKey = key as! Key
            if let value = self[tKey] {
                return (tKey, value)
            }
         }
        return nil
    }
}

事实是,CollectionType 没有与字典的 'Key' 占位符相对应的占位符。并非所有 CollectionType 都由键值对组成,因此使 CollectionType 具有键/值类型方法没有意义。例如,另一个 CollectionType 是 Array - 对于数组,getElement return 是什么?

如果可以更改协议的声明,您也可以通过关联类型要求来解决此问题:

protocol CollectionAccess: CollectionType {
    typealias T = Hashable
    func getElement(key: T) -> Self.Generator.Element?
}

现在,您的字典实现无需修改即可按预期工作。

(但现在您不能创建类型为 [CollectionAccess] 的数组(只能作为泛型函数中的参数,其中 is 必须为 "homogeneous"))