简单的问题,但我不知道为什么!
创建集合
公共变量hm:[B:Int] = [:]
A类-定义:
class A : Hashable {
var x : Double = 0
var y : Double = 0
init(x : Double, y : Double) {
self.x = x
self.y = y
}
var hashValue : Int {
get {
// IMPORTANT!!! Do some operations to generate a unique hash.
return ObjectIdentifier(self).hashValue
}
}
static func == (lhs: A, rhs: A) -> Bool {
//return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
return (lhs.x == rhs.x && lhs.y == rhs.y)
}
}
class B : A {
}
用于获取收藏价值的功能检查-hm。
func check(a1 : B, a2 : B){
print("\na1: \(a1.x) \(a1.y)")
if let y1 = hm[a1] {
print(y1)
}else{
print("false a1")
}
print("\na2: \(a2.x) \(a2.y)")
if let y2 = hm[a2] {
print(y2)
}else{
print("false a2")
}
}
,最后创建一个函数test()是测试的主要内容。
func test() -> Void {
let a1 : B = B(x: 9.0, y: 12.0)
let a2 : B = B(x: 19.0, y: 42.0)
hm[a1] = 99
hm[a2] = 20
let a3 : B = B(x: 9.0, y: 12.0)
let a4 : B = B(x: 19.0, y: 42.0)
print("----Content of hm-----")
for (key, val) in hm {
print("x: \(key.x) | y: \(key.y) | val: = \(val)")
}
check(a1: a3, a2: a4)
}
在主线程上调用test()。 输出为:
----Content of hm-----
x: 19.0 | y: 42.0 | val: = 20
x: 9.0 | y: 12.0 | val: = 99
a1: 9.0 12.0
99
a2: 19.0 42.0
false a2
为什么打印“ false a2”-> 在馆藏内未找到a2 嗯?
对于比较2个对象,我使用:(lhs.x == rhs.x && lhs.y == rhs.y)。 (如果使用ObjectIdentifier,则比较结果始终为false)
谢谢您的解释。
答案 0 :(得分:0)
我不知道为什么它的行为确实如此,但是我可以说出问题所在:您实施的Hashable
错误。
符合Hashable
的一个重要条件是“相等的对象具有相同的hashValue
”,这在您的情况下是不正确的。一旦打破了这一基本假设,所有依赖于此的代码都可能会崩溃(例如Dictionary
)。
在此示例中,您应该使A
处理身份(在这种情况下==
与===
相同),或者处理值(在这种情况下{{1 }}仅取决于hashValue
和x
)。
这里要注意的重要一点是y
不仅意味着“它是一个可以产生自身哈希值的值”,而且实际上是Hashable
的子协议。因此,它的真正含义是“可以检查是否相等的对象,还可以使用它可以产生的哈希值进行初步的相等性检查”。
答案 1 :(得分:0)
删除hashValue
的实现,并替换为插入:
func hash(into hasher: inout Hasher) {
x.hash(into:&hasher)
y.hash(into:&hasher)
}