我正在创建一个类似于a的结构String,除了它只处理Unicode UTF-32标量值.因此,它是一个数组UInt32.(有关更多背景,请参阅此问题.)
我希望能够将自定义ScalarString结构用作字典中的键.例如:
var suffixDictionary = [ScalarString: ScalarString]() // Unicode key, rendered glyph value
// populate dictionary
suffixDictionary[keyScalarString] = valueScalarString
// ...
// check if dictionary contains Unicode scalar string key
if let renderedSuffix = suffixDictionary[unicodeScalarString] {
// do something with value
}
Run Code Online (Sandbox Code Playgroud)
为此,ScalarString需要实现Hashable协议.我以为我可以这样做:
struct ScalarString: Hashable {
private var scalarArray: [UInt32] = []
var hashValue : Int {
get {
return self.scalarArray.hashValue // error
} …Run Code Online (Sandbox Code Playgroud) 为了解决这个问题,我一直在玩一个实现Hashable Protocol的自定义结构.我正在尝试查看等效运算符overload(==)被调用多少次,具体取决于填充a时是否存在哈希冲突Dictionary.
更新
@matt编写了一个更清晰的自定义结构示例,该结构实现了Hashable协议并显示了调用的频率hashValue和==调用次数.我在下面复制他的代码.要查看我的原始示例,请查看编辑历史记录.
struct S : Hashable {
static func ==(lhs:S,rhs:S) -> Bool {
print("called == for", lhs.id, rhs.id)
return lhs.id == rhs.id
}
let id : Int
var hashValue : Int {
print("called hashValue for", self.id)
return self.id
}
init(_ id:Int) {self.id = id}
}
var s = Set<S>()
for i in 1...5 {
print("inserting", i)
s.insert(S(i))
}
Run Code Online (Sandbox Code Playgroud)
这会产生结果:
/*
inserting 1
called …Run Code Online (Sandbox Code Playgroud) 我最近了解了一些有关散列值的知识,因此也听说了有关散列冲突的问题。
因此,我想知道:一个人该如何处理?
例如,Swift的Dictonary键使用哈希值。我假设它通过哈希查找其值。那么Swift如何Dictionary存储恰好具有相同哈希值的不同键的值呢?
我在Swift中有一个结构,如下所示:
internal struct MapKey {
internal let id: String
internal let values: [String:String]
}
extension MapKey: Equatable {}
func ==(lhs: MapKey, rhs: MapKey) -> Bool {
return lhs.id == rhs.id && lhs.values == rhs.values
}
Run Code Online (Sandbox Code Playgroud)
我现在需要使用MapKey作为Swift字典中的键,这需要MapKey符合Hashable协议.
对于像这样的结构,Hashable的正确实现是什么?
extension MapKey: Hashable {
var hashValue: Int {
return ??? // values does not have a hash function/property.
}
}
Run Code Online (Sandbox Code Playgroud)
我一直在做一些研究,但未能确定散列字典的正确方法是什么,因为我需要能够为values属性本身生成散列值.任何帮助深表感谢.