在Swift中Hashable和Equalable有什么用途?什么时候用哪个?

在Swift中Hashable和Equalable有什么用途?什么时候用哪个?,swift,Swift,我知道Hashable是从Equatable继承的,但是你能给我一个需要Hashable而不仅仅是Equatable的例子吗。谢谢 当您符合Hashable时,您提供了一个返回self散列值的方法 当您符合equalable时,您将提供一个方法,返回给定对象和self是否相等 它们似乎有两个非常不同的用途,为什么可哈希继承可均衡?因为两个相等对象的哈希值相等 使用Hashable和equalable可以做什么,不能做什么 equalable的用途比Hashable更为有限。它只能比较两个对象的相

我知道Hashable是从Equatable继承的,但是你能给我一个需要Hashable而不仅仅是Equatable的例子吗。谢谢

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

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

它们似乎有两个非常不同的用途,为什么
可哈希
继承
可均衡
?因为两个相等对象的哈希值相等

使用
Hashable
equalable
可以做什么,不能做什么

equalable
的用途比
Hashable
更为有限。它只能比较两个对象的相等性,就是这样

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

if objA.hashValue > objB.hashValue
这也意味着您可以使用
Hashable
对对象进行排序


最后但并非最不重要的一点是,您可以使用
Hashable
对象作为贴图的键!这是因为“地图”的键无法复制,因此系统如何检查您是否在其中放置了重复项?它使用密钥的散列值

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

除此之外,您不应该仅根据对象的哈希值来确定对象的任何
可均衡
可比较

简而言之,
Hashable
是从
equalable
派生出来的,因为仅仅通过测试两个对象的
hashValue
是否相等,无法安全地确定它们是否相等

更多详细信息

根据:

散列值是一个Int值,对于所有进行相同比较的对象来说,它都是相同的,因此如果
A==b
,则表示
A.hashValue==b.hashValue

然而,情况并非如此。如果
a.hashValue==b.hashValue
,则它不遵循
a==b

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

避免尝试这样做

说:

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

if objA.hashValue > objB.hashValue
不,您要比较的是(可能发生冲突的)对象的散列值,而不是对象本身

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

Hashable
本身的用途非常有限,除了
equalable
。为了安全起见,您应该始终测试对象本身。

我不知道swift,但是
Hashable
用于排序的可能性几乎为零。它通常用于无序的哈希表/字典。通常有一个
可比较的
接口用于实际生成可排序类型;哈希代码的排序是一致的,但在大多数情况下是没有意义的。而且,是的,看起来像Swift,这就是
Hashable
要使用的。@LeoDabus:Swift可以让你这样做,但它毫无意义。对于任何不足以有效自哈希的数据,按哈希代码排序很少是有意义的排序(一个
int
可能会对自身进行哈希,因此按哈希代码排序在那里是有意义的,但对于字符串和其他高级对象,它可能是一致的,但它是100%任意的)。我也不认为哈希表是为排序而发明的。但为什么会在那里?在Swift字典中,键必须符合哈希值。为什么会这样?既然不允许重复,那么这样做就足够了。为什么系统会喜欢(并要求)使用Hashable?@HuangChao:请继续阅读<代码>词典基于它们。其思想是,通过使用散列,您可以将成员资格测试、检索和删除转换为(大致)固定成本操作(在big-O表示法中,
O(1)
),其中在正常序列上的相同操作需要对每个元素进行线性扫描(
O(n)
)。如果你有10000个元素,执行10000个相等性检查以确定针不在大海捞针会变得昂贵;在大多数情况下,哈希表可以将其简化为一些测试。我想更多地了解在Hashable和Equatable之间迭代大型数组时的性能差异,因为这应该成为决定一个对象是否应该是可散列的因素。如果有两个对象的散列值不相等,那么情况会怎样呢。例如,您有一个对象字典,如果ObjectIdentifier在字典中不同,则每个实例都应被视为不同。但是,如果所有值都相同,则其他值相同。(这是针对类实例的)然后呢?