在下面的代码中,我收到错误[String : Double] does not conform to Hashable
。我该如何解决这个问题?
我看到了Hashable协议不符合的问题,但我想知道为什么会出现这种情况,其他方式也有效。只有' Key'在字典中需要确认Hashable?一些解释会有所帮助
enum someEnumType {
case First(String, (Int, Int)->Int)
case Second (String, Int)
}
// var operations = [someEnumType : [String : Double]](); <--- This syntax Works
var operations = [[String : Double] : someEnumType ](); <--- But this does not work, ideally - i want this.
答案 0 :(得分:1)
字典也称为†哈希表;他们通过散列关键来工作。所以,是的,确实需要Hashable
。该值不是因为要点是按键查找值。
†严格地说,可以实现没有散列的字典,但实际上,编程语言中称为字典的数据结构通常被理解为散列映射。在Swift中,Dictionary
文档将其指定为“基于散列的映射”。
答案 1 :(得分:0)
是的,钥匙需要可以清洗。
答案 2 :(得分:0)
您应该可以通过使用NSString而不是String来解决此问题。
答案 3 :(得分:0)
你是对的,只有Dictionary的密钥必须符合Hashable协议。
以您希望的方式使用Dictionary的最直接方式可能是定义您自己的密钥类型。 struct
在这里有意义;它提供了与[String: Double]
关键优惠相同的价值语义,并且很容易定义:
struct MyKey {
let myString: String
let myDouble: Double
}
当然,它必须是可以用作Dictionary键的,因此我们添加Hashable
一致性:
struct MyKey: Hashable {
let myString: String
let myDouble: Double
var hashValue: Int {
return self.myString.hashValue ^ self.myDouble.hashValue
}
}
我在那里做了一个可爱的技巧来计算这个键类型的“unique-ish”哈希值:只是字符串的XOR和double的哈希值。我不保证唯一性,但对大多数情况来说它应该足够好。计算一个更好的哈希值是一个练习,如果你愿意,我会留给你(但它可以正常工作)。
最后,要符合Hashable
,还必须符合Equatable
。在我们的例子中,我们只是检查每个键的属性是否与其他键匹配,以确定键是否相等。全面实施:
struct MyKey: Hashable {
let myString: String
let myDouble: Double
var hashValue: Int {
return self.myString.hashValue ^ self.myDouble.hashValue
}
}
func ==(lhs: MyKey, rhs: MyKey) -> Bool {
return lhs.myString == rhs.myString && lhs.myDouble == rhs.myDouble
}
现在,您可以像这样定义词典:
var operations = [MyKey : someEnumType ]()
并添加如下条目:
let myFirstKey = MyKey(myString: "Hello", myDouble: 1.0)
operations[myFirstKey] = someEnumType