【发布时间】:2018-05-23 07:42:32
【问题描述】:
目前我正在研究一种数据结构,旨在唯一地存储键值对并保持它们按键排序。从本质上讲,它是一个排序字典,因此我希望尽可能多地保留 Swift 的 Collection 和 Dictionary 语义。
在文档和 Swift 源代码中(尽我所能),字典有两个下标。一种是最常用的subscript by key (Github source):
extension Dictionary {
...
public subscript(key: Key) -> Value? {
@inline(__always)
get {
return _variantBuffer.maybeGet(key)
}
set(newValue) {
if let x = newValue {
// FIXME(performance): this loads and discards the old value.
_variantBuffer.updateValue(x, forKey: key)
}
else {
// FIXME(performance): this loads and discards the old value.
removeValue(forKey: key)
}
}
}
...
}
第二个是subscript by position/index (Github) source),作为其符合 Collection 协议的一部分:
extension Dictionary: Collection {
...
public subscript(position: Index) -> Element {
return _variantBuffer.assertingGet(position)
}
...
}
当将这些与由 Int 以外的其他内容作为键的字典一起使用时,它们的行为与预期完全一样,因为下标由不同的参数类型区分,即:String 与 Int。
let stringKeys = ["One": 1, "Two": 2, "Three": 3]
stringKeys["One"] // 1
stringKeys[1] // ("Two", 2)
Ints 用作键时,根据需要使用键下标。
let intKeys = [1: "One, 2: "Two, 3: "Three"]
intKeys[1] // "One"
Dictionary 类型是如何做到这一点的?在我看来,下标的 Index 和 Key 参数都是 Int 并且编译器不应该知道哪个是预期的。事实上,当我为我的自定义字典实现相同的下标时,当我使用 Int 键对其进行测试时,编译器会给出确切的错误——“‘下标’的歧义使用”。
起初我想知道是否一个是协议扩展中提供的默认值并被更具体的实现覆盖,但据我所知,情况并非如此。我唯一的其他理论是Index 是除“Int”之外的其他类型,因此它仍然是明确的,但我找不到任何可以证实这一点的方法。任何人都可以对此有所了解吗?除了我的迫切需要之外,我还想了解 Swift 中的一些非常聪明的行为。
感谢大家的阅读和帮助!
【问题讨论】:
标签: swift dictionary ambiguous subscript