【问题标题】:Extending CollectionType in Swift 2在 Swift 2 中扩展 CollectionType
【发布时间】:2015-06-26 17:26:33
【问题描述】:

所以我正在尝试在 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
    }
}

编译时会抛出一个错误:

错误:类型“字典”不符合协议 'CollectionAccess' 扩展字典: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]

现在的问题是:

错误:不能为“字典”类型的值下标 “K”类型的索引 自我[键]

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

【问题讨论】:

  • 我不确定这是否可行 - CollectionType 没有对应于 Dictionary 的“Key”泛型的泛型。 IE。并非所有 CollectionType 都由键值对组成,因此使 CollectionType 具有 Key /Value 类型方法是没有意义的。例如,另一个 CollectionType 是 Array - 数组的元素返回是什么?
  • 换句话说,'Key' 和 'Value' 是 Dictionary 中的占位符,因此您无法在 CollectionType 协议扩展的方法签名中访问它们。如果我错了,请原谅我!

标签: generics dictionary swift2


【解决方案1】:

'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 没有对应于 Dictionary 的“Key”占位符的占位符。并非所有 CollectionType 都由键值对组成,因此使 CollectionType 具有 Key / Value 类型方法是没有意义的。例如,另一个 CollectionType 是 Array - getElement 会为数组返回什么?

【讨论】:

  • 感谢@james_alvarez,现在这似乎可行。我同意你的看法,但我还是觉得有点不对劲。我仍在尝试围绕声明中引用 Self 的协议扩展以及所有其他内容。
【解决方案2】:

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

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

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

(但现在您不能创建[CollectionAccess] 类型的数组(仅作为必须“同质”的泛型函数中的参数))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多