在Programming in Scala中,作者写道Scala的==
函数比较了值相等而不是引用相等。
这在列表中按预期工作:
scala> List(1,2) == List(1,2)
res0: Boolean = true
但它不适用于数组:
scala> Array(1,2) == Array(1,2)
res1: Boolean = false
作者建议改为使用sameElements函数:
scala> Array(1,2).sameElements(Array(1,2))
res2: Boolean = true
作为解释,他们写道:
虽然这看似不一致,但鼓励对两个可变数据结构的相等性进行明确测试是语言设计者的一种保守方法。从长远来看,它可以帮助您避免条件下的意外结果。
这是什么意思?他们在谈论什么样的意外结果?如果数组在相同位置包含相同的元素,那么我还能从数组比较中得到什么呢?为什么equals函数适用于List
但不适用于Array
?
如何让equals函数在数组上起作用?
答案 0 :(得分:27)
本书中提供的解释确实值得怀疑,但公平地说,当它们写作时更加可信。在2.8中它仍然是正确的,但我们必须改进不同的推理,因为正如你所注意到的,所有其他集合都进行了元素比较,即使它们是可变的。
为了让Arrays看起来像收集的其他部分,已经流了很多血,但这是一个极其漏洞的抽象,最终它是不可能的。我认为,正确地确定我们应该转向另一个极端,并按照它们的方式提供本机阵列,使用隐式机制来增强其功能。其中最明显的是toString和equals,因为它们都没有在Arrays上以合理的方式运行,但我们不能用隐式转换拦截这些调用,因为它们是在java.lang.Object上定义的。 (转换仅在表达式未进行类型检查时发生,并且始终键入check。)
所以你可以选择你的解释,但最终数组的基本架构会有不同的处理方式,而且没有办法在没有付出代价的情况下提出这个问题。这不是一个糟糕的情况,但这是你必须要注意的事情。
答案 1 :(得分:7)
这个确切的问题已经多次表达过(我自己也见过Strange behaviour of the Array type)。
请注意,只有Array
集合不支持==
,所有其他集合都支持Array
。根本原因是array
是Java {{1}}。
答案 2 :(得分:-3)
所有关于参考透明度。我们的想法是,如果两个值为==
,那么您使用哪一个值无关紧要。如果你有两个具有相同内容的数组,那么你修改哪一个显然很重要,所以==
返回false,除非它们是相同的。