Swift中Hashable和Equatable的用途是什么?什么时候使用?

Hua*_*hao 5 swift

我知道Hashable继承自Equatable,但您能否举一个需要Hashable的示例,而不仅仅是Equatable。谢谢!

小智 9

您可以hashValue用来确定两个对象是否彼此相等。

除此之外,您不应仅根据对象的散列值对对象进行任何EquatableComparable确定。

简而言之,HashableEquatable因为您不能仅仅通过测试它们的相等性来安全地确定两个对象是否相等hashValue

更多细节

根据Swift 文档

散列值是一个 Int 值,对于相等比较的所有对象都相同,因此如果a == b,它遵循a.hashValue == b.hashValue

然而,反之则不然。如果a.hashValue == b.hashValue,它并没有遵循a == b

虽然有完美的散列函数可以返回unique值,但散列函数可以hashValue为两个或多个不同的对象返回相同的值。这称为散列冲突

避免尝试这样做

Sweeper 的回答说:

对于 Hashable,因为您可以获得代表对象的数字,所以您可以将对象视为数字。您可以比较对象:它是否小于、大于或等于另一个对象,就像您处理数字一样:

不。您要比较的是(可能发生碰撞的)对象的哈希值,而不是对象本身。

  • 比较一个哈希值是小于还是大于另一个哈希值对于对象来说是没有意义的。
  • 关于相等性,只有散列函数为对象返回一个完全唯一的值时,它才会成立。

Hashable除了Equatable. 为了安全起见,您应该始终测试对象本身。


Swe*_*per 6

当您符合 时Hashable,您提供了一个返回 的哈希值的方法self

当您符合 时Equatable,您提供了一个方法,该方法返回给定对象 和self是否相等。

它们似乎服务于两个截然不同的目的,为什么Hashable继承Equatable?因为两个相等对象的哈希值是相等的!

你可以用Hashableand做什么和不能做Equatable什么?

Equatable具有比 更有限的用途Hashable。它只能比较两个对象的相等性,仅此而已。

对于Hashable,因为您可以获得代表对象的数字,所以您可以将对象视为数字。您可以比较对象:它是否小于、大于或等于另一个对象,就像您处理数字一样:

if objA.hashValue > objB.hashValue
Run Code Online (Sandbox Code Playgroud)

这也意味着您可以使用Hashable.

最后但并非最不重要的一点是,您可以使用Hashable对象作为地图的键!这是因为maps的key不能重复,那么系统如何检查你是否放入了重复的item呢?它使用键的哈希值!

  • 我不知道 swift,但是“Hashable”用于排序的可能性几乎为零。它通常与无序的哈希表/字典一起使用。通常有一个“Comparable”接口用于实际创建可排序类型;对哈希码进行排序是一致的,但在大多数情况下毫无意义。 (4认同)
  • @HuangChao:阅读[哈希表](https://en.wikipedia.org/wiki/Hash_table);`Dictionary` 是基于它们的。这个想法是通过使用散列,您可以将成员资格测试、检索和删除转换为(大致)固定成本操作(在大 O 表示法中,`O(1)`),其中对正常序列的相同操作需要一个每个元素的线性扫描(`O(n)`)。如果您有 10,000 个元素,执行 10,000 次相等性检查以确定针不在大海捞针中会变得昂贵;在大多数情况下,哈希表可以将其减少到少数测试。 (2认同)