Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么不';Swift类是否默认可哈希?_Swift_Class - Fatal编程技术网

为什么不';Swift类是否默认可哈希?

为什么不';Swift类是否默认可哈希?,swift,class,Swift,Class,类有一个标识,它们的hashValue很容易成为它们在内存中的地址。为什么不是这样 因为基于身份的hashValue并不是很有用 下面是一个例子: 假设我将来自两个不同来源的两组数据进行组合,并检查重复项。一种常见的方法是将两者都添加到集合。这些对象肯定具有唯一的标识(即不同的地址)。如果这意味着它们还具有唯一的hashValues,则不会检测到重复项 使用Set进行重叠的全部原因首先是因为hashValue暗示了什么是重复的定义。您的建议将打破这一点。我非常确定,对象的哈希/摘要应该基于其内容

类有一个标识,它们的hashValue很容易成为它们在内存中的地址。为什么不是这样

因为基于身份的
hashValue
并不是很有用

下面是一个例子:

假设我将来自两个不同来源的两组数据进行组合,并检查重复项。一种常见的方法是将两者都添加到
集合
。这些对象肯定具有唯一的标识(即不同的地址)。如果这意味着它们还具有唯一的
hashValue
s,则不会检测到重复项


使用
Set
进行重叠的全部原因首先是因为
hashValue
暗示了什么是重复的定义。您的建议将打破这一点。

我非常确定,对象的哈希/摘要应该基于其内容,而不是其标识或地址-如果对象具有“不相关”状态(例如缓存值),则它不应该是哈希计算的一部分,但Swift编译器不知道这一点。如果哈希值基于对象的地址,那么使用内存碎片整理的运行时(如CLR,它将在GC暂停期间移动内存中的对象)从根本上与Swift不兼容。很抱歉,我不明白为什么依赖对象标识是不谨慎的?如果在堆上分配了一个对象,那么它的指针实际上就是它的标识。似乎有必要且合理地假设,不,是的,一个对象的内存地址确实是它的标识。(例如,这就是为什么比较引用的运算符(
==
)被称为“与运算符相同”)。但我们在这里讨论的是不同的东西。让
s
成为类型
T
的所有实例的集合。Swift相等运算符(
=
)是一个(事实上,是其中最明显的例子),可用于将
S
划分为。当
a
b
两个实例是同一等价类的成员时,表示为
a==b
返回
true
。如果
c
a
b
处于不同的等价类中,则
a==c
a==c
都将返回
false
。通过将对象标识与对象相等合并,实际上是将集合
S
划分为
|S
(表示“S的大小”)不同的分区,其中每个实例(每个对象)是其等价类的唯一成员(因为它是唯一具有该引用的对象,并且每个其他引用都是不同的)。非常有用的是,两个引用有两个不同的实例(即不同的标识)比较相等。我想不出在任何情况下,保证没有两个不相同的对象必须作为不相等的对象进行比较是有用的。此外,如果你真的想要一个相等于身份的操作符,你已经在
===
==
中有了它,它故意作为一个单独的概念存在,一个“合并”的操作符以前,等价类被划分为新的大型等价类,每个类都有多个成员,它们共享一些特定的属性。尽管如此,我并没有真正谈论
hashValue
,因为相等是一种更简单的方式来谈论这个问题。
hashValue
只是一种相等的启发式方法。如果两个对象具有ame hashValues,它们比任何其他对象(具有不同的hashValues)进行同等比较的可能性更高。通过哈希搜索集合中的对象时,通过哈希可以剔除集合的大部分,因此不需要对所有元素执行相等性检查。相反,只需要对具有相同哈希值的对象集执行相等性检查。