平等有多难?

时间:2012-05-31 03:44:50

标签: types theory equality

例如,在Javascript中[1,2,3] === [1,2,3][1,2,3] == [1,2,3]都是假的。即使是空数组的简单情况也是错误的。原因是数组是引用类型,[1,2,3][1,2,3]作为引用不同。 Javascript在这方面并不是唯一的,几乎每种语言都将实现等同作为引用相等,除了最基本的类型,如整数和一些内置类型。

为什么会这样?使默认的相等运算符变得更强大有什么困难?因此,不仅仅是比较参考文献,为什么还要如此难以比较结构属性呢?

我知道很多语言都提供了重载某些运算符以表示其他内容的工具,因此==将意味着你想要的意思而不是通常的弱引用相等。我的问题不是语言是否提供了这样的设施,而是为什么默认的相等运算符不是更合理的,因此[1,2,3] == [1,2,3]默认情况下评估为真,并且不需要程序员干预。

在python中,上面的示例计算结果为true,但是如果定义以下类

class A:
  def __init__(self, prop):
    self.prop = prop

然后将a = A(1)b = A(1)进行比较,那么即使结构ab相同,答案仍然是假的,如果没有办法将它们区分开来所有你知道的是定义对象的位模式。

3 个答案:

答案 0 :(得分:2)

并非所有语言都这样做。 C ++在对象上使用==来表示相等(尽管指针上的==表示引用相等)。我相信(虽然我不完全确定)D编程语言为值相等保留==,为参考相等保留is运算符。

我认为这只是JavaScript和其他几种语言的设计决定。没有必要这样做。

答案 1 :(得分:2)

并非所有语言都按照您描述的方式工作。例如,在Python中==是相等的,is是引用比较:

>>> a = [1,2,3]
>>> b = [1,2,3]
>>> a == b
True
>>> a is b
False

答案 2 :(得分:0)

  

几乎每种语言都将等同实现为引用相等

正如此问题的types标记所示,许多语言将等同作为该类型的行为实现。这是有道理的:大多数类型都有一些可以在实例上更改的属性,而不会改变该实例的语义“值”。

所以我给出的答案是:平等并不难,由类型决定哪些实例是平等的。没有这种明确决定的任何违约应该是保守的。

如果您要创建自定义类型,那么您有责任自行决定;如果语言支持继承,则使用它来表达您的决定“相等应该表现得像其他更基本的类型”。否则,为类型显式编写相等性测试,就像您认为具有正确行为的现有类型一样。