平等是否意味着相等的哈希值?

时间:2017-09-04 15:09:30

标签: swift hash identity equality semantics

我目前正在研究图形数据类型,在这种情况下,我已经考虑了很多关于身份和平等的语义问题。

我现在的情况如下。我有一个Vertex类型:

final class Vertex<T>: Hashable {

  static func ==(lhs: Vertex, rhs: Vertex) -> Bool { 
    return lhs === rhs
  }

  var value: T

  var hashValue: Int { 
    return ObjectIdentifier(self).hashValue 
  }

}

正如你所看到的,平等是由身份决定的。我之所以这样做是出于特定于图数据类型的原因,但它基本上归结为,顶点应该通过它们的标识来查看,因此只有它们相同时才被视为相等(相同< / em>)vertex。

现在哈希值也由身份确定(使用ObjectIdentifier)。这似乎是获取哈希值的最简单方法,并且似乎与此类型的相等概念很好地吻合。

但这让我想到了...... 它是否在语义上“不正确”(或者,如果你愿意,则不合逻辑)通过value属性(如果T符合Hashable)确定哈希值。
在这种情况下,两个Vertex可以一致地具有相同的哈希值(不仅仅是对程序的一次调用),而不被认为是相等的。这似乎不对。

反过来说:实例的相等性是否应该意味着哈希值的相等是否明智?

2 个答案:

答案 0 :(得分:3)

来自Hashable的文档:

  

“由类型的hashValue属性提供的哈希值是一个整数,对于任何两个同等比较的实例都是相同的。也就是说,对于同一类型的两个实例a和b,如果a == b则a.hashValue == b.hashValue。反之则不然:具有相同哈希值的两个实例不一定彼此相等。“

换句话说,如果==返回true,则hashValue必须为两个对象返回相同的值。

答案 1 :(得分:1)

哈希的要求是,如果两个值ab相同,那么a.hashvalue == b.hashvalue。然而,这并不意味着反过来是正确的。如果两个散列值相同,则散列项可能不相同。所以当你这么说时

  • “实例的相等应该意味着它们的哈希值是否相等?”这实际上是一项要求。
  • “两个顶点可以一致地具有相同的哈希值(不仅仅是对程序的一次调用),而不被认为是相等的。这看起来并不正确” - 实际上这是可能的。