Answers:
您通常使用==
,它会路由到equals
,但会null
正确处理。引用等式(很少使用)为eq
。
3 == BigInt(3)
和BigInt(3) == 3
都是真实的。但是,3.equals(BigInt(3))
是错误的,而是BigInt(3).equals(3)
真实的。因此,更喜欢使用==
。避免equals()
在Scala中使用。我认为==
隐式转换效果很好,但equals()
事实并非如此。
new java.lang.Integer(1) == new java.lang.Double(1.0)
是真的却new java.lang.Integer(1) equals new java.lang.Double(1.0)
是假的呢?
equals
方法,用于比较每个实例的内容。这与equals
Java中使用的方法相同==
运算符进行比较,而不必担心null
引用eq
的方法来检查,如果两个参数是EXACTLY相同的参考。建议不要使用,除非您了解它的工作原理,并且通常equals
会根据您的需要工作。并确保仅将此AnyRef
参数与参数一起使用,而不仅仅是Any
注意:在情况下equals
,就像Java中一样,如果您切换参数,它可能不会返回相同的结果,例如1.equals(BigInt(1))
将返回false
相反的地方true
。这是因为每个实现仅检查特定类型。基本数字不检查第二个参数是否为Number
nor BigInt
类型,而仅检查其他基本类型
该AnyRef.equals(Any)
方法是被子类覆盖的方法。Java规范中的一种方法也已经应用于Scala。如果在未装箱的实例上使用,则将其装箱以调用它(尽管在Scala中隐藏;在Java中使用int
-> 更明显Integer
)。默认实现只是比较引用(如Java)
该Any.==(Any)
方法比较两个对象,并允许其中一个参数为null(就像使用两个实例调用静态方法一样)。它比较两者是否均为null
,然后equals(Any)
在装箱实例上调用方法。
该AnyRef.eq(AnyRef)
方法仅比较引用,即实例在内存中的位置。此方法没有隐式装箱。
1 equals 2
将返回false
,因为它重定向到Integer.equals(...)
1 == 2
将返回false
,因为它重定向到Integer.equals(...)
1 eq 2
将不会编译,因为它要求两个参数均为类型 AnyRef
new ArrayList() equals new ArrayList()
将返回true
,因为它检查内容new ArrayList() == new ArrayList()
将返回true
,因为它重定向到equals(...)
new ArrayList() eq new ArrayList()
将返回false
,因为两个参数都是不同的实例foo equals foo
会返回true
,除非foo
是null
,然后会抛出一个NullPointerException
foo == foo
将返回true
,即使foo
是null
foo eq foo
将返回true
,因为两个参数都链接到相同的引用有之间的有趣的差异==
,并equals
为Float
和Double
类型:他们对待NaN
不同的:
scala> Double.NaN == Double.NaN
res3: Boolean = false
scala> Double.NaN equals Double.NaN
res4: Boolean = true
编辑:正如指出的评论- “这也恰好在Java中” -取决于正是这就是:
public static void main(final String... args) {
final double unboxedNaN = Double.NaN;
final Double boxedNaN = Double.valueOf(Double.NaN);
System.out.println(unboxedNaN == unboxedNaN);
System.out.println(boxedNaN == boxedNaN);
System.out.println(boxedNaN.equals(boxedNaN));
}
这将打印
false
true
true
因此,在进行相等性比较时的unboxedNan
收益率false
是因为这是IEEE浮点数定义它的方式,并且确实应该在每种编程语言中发生(尽管它在某种程度上与身份的概念混淆了)。
==
当我们在比较对象引用时,带框的NaN对于在Java中使用的比较而言,它的结果为true 。
对于这种equals
情况,我没有任何解释,恕我直言,它的行为应与未==
装箱的double值相同,但事实并非如此。
转换为Scala后,问题变得更加复杂了,因为Scala将原始类型和对象类型统一Any
为所需的类型,并转换为原始double和盒装Double。因此,scala ==
显然可以归结为原始NaN
值的比较,但是equals
使用了在装箱的Double值上定义的值(存在很多隐式转换魔术,并且有很多东西被放大为double RichDouble
)。
如果您真的需要找出是否确实NaN
有用,请使用isNaN
: