【问题标题】:Swift: Constrained extension on Dictionary by ElementSwift:Dictionary by Element 的约束扩展
【发布时间】:2015-07-30 22:08:22
【问题描述】:

我想在 Dictionary 上创建一个扩展,它只影响类型为 [String:AnyObject] 的字典,这是从解析的 JSON 字典返回的数据类型。以下是我的设置方式:

typealias JSONDictionary = [String : AnyObject]
extension Dictionary where Element:JSONDictionary {
    // Some extra methods that are only valid for this type of dictionary.
}

Xcode 在Element 上生成一个错误,说它是一个未声明的类型。但是, Dictionary 定义的第一行 是一个typealias 声明的Element。我在这里做错了什么?

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    Element 是一个元组:

    typealias Element = (Key, Value)
    

    这与您尝试将其与(字典)进行比较的类型不匹配。你甚至不能说像where Element:(String, AnyObject) 这样的话,因为元组不是这样子类型的。例如,考虑:

    var x: (CustomStringConvertible, CustomStringConvertible) = (1,1)
    var y: (Int, Int) = (1,1)
    x = y // Cannot express tuple conversion '(Int, Int)' to ('CustomStringConvertible', 'CustomStringConvertible')
    

    比较:

    var x1:CustomStringConvertible = 1
    var y1:Int = 1
    x1 = y1 // No problem
    

    我怀疑你得到“未声明的类型”是因为Element 不再是未绑定的类型参数,而是绑定的类型参数。 Dictionary 符合 SequenceType 这里。所以你不能对它进行参数化(至少不能在一个步骤中;你必须通过另一层类型参数来追踪它以发现它“最终”未绑定)。这似乎是一个糟糕的错误消息,但我怀疑它是从“可能在这里使用的类型列表中未声明的类型”中冒出来的。我认为值得打开雷​​达以获得更好的错误消息。

    相反,我认为你的意思是:

    extension Dictionary where Key: String, Value: AnyObject { }
    

    为 Swift 2 编辑:

    这不再是合法的 Swift。您只能基于协议进行约束。等效代码是:

    protocol JSONKey {
        func toString() -> String
    }
    extension String: JSONKey {
        func toString() -> String { return self }
    }
    
    extension Dictionary where Key: JSONKey, Value: AnyObject { ... }
    

    【讨论】:

    • 感谢您如此雄辩地解释问题和解决方案!
    • 我收到<unknown>:0: error: type 'Key' constrained to non-protocol type 'String'
    • @fpg1503 从那时起,Swift 发生了很大变化。我已经更新了答案
    • 我可能会使用StringLiteralConvertible 而不是创建一个无用的协议来愚弄编译器。
    • @fpg1503 我没有欺骗那里的编译器。我正在制定我想要支持的东西的协议。我记得 StringLiteralConvertible 没有“将字符串取出”方法,所以我认为它不会起作用。
    猜你喜欢
    • 1970-01-01
    • 2013-12-26
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多