什么';在Scala中,`null==last`和`null eq last`之间的区别是什么?

什么';在Scala中,`null==last`和`null eq last`之间的区别是什么?,scala,equals,Scala,Equals,我在scala 2.7.7的内置类MessageQueue.scala中看到,在第164行附近,它是: def extractFirst(p: Any => Boolean): MessageQueueElement = { changeSize(-1) // assume size decreases by 1 val msg = if (null eq last) null else { ... } } 我不明白val msg=if(null eq last)null为

我在scala 2.7.7的内置类
MessageQueue.scala
中看到,在第164行附近,它是:

def extractFirst(p: Any => Boolean): MessageQueueElement = {
changeSize(-1) // assume size decreases by 1

val msg = if (null eq last) null
else {
    ...
  }
}

我不明白
val msg=if(null eq last)null
为什么它使用
eq
,而不是
null
。如果我写
If(last==null)null
,是否正确?有什么区别吗?

==
的任一侧为
null
=
的第一个操作数计算结果为null时,Scala将不会调用
equals
。因此,在这种情况下,是的,
x==null
x eq null
相同;不调用
equals
方法。请注意以下情况

考虑这一点:

class X {
   // this is just for testing
   // any equals that returns true when the other object is null
   // is arguably broken. thus even though it may be invoked
   // the end semantics should remain the same
   override def equals(x: Any) = true
}
var x = new X()
x == null // false -- compiler optimization?
null == x // false
var y = null
y == x // false -- see documentation below, y is null, x is not
x == y // true  -- x does not evaluate to null, equals invokes
x eq y // false
请注意:

(new X()) == null
结果显示一条警告,表示“一个新对象”永远不会等于(null)

我怀疑为
x==y
发出的代码可能比
x==null
发出的代码稍多/稍有不同(如果必须调用equals),但没有进行检查

快乐编码


Scala语言规范第6.3节(空值)中有这样一句话:

null值的类型为scala.null,因此与每个引用都兼容 类型。它表示引用特殊“null”对象的引用值。这个物体 实现类scala.AnyRef中的方法,如下所示:

  • 如果参数x也是“null”对象,则[null]eq(x)和[null]==(x)返回true
  • ne(x)和=(x)如果参数x不是“null”对象,则返回true
  • isInstanceOf[T]始终返回false
  • asInstanceOf[T]在T符合以下条件时返回“null”对象本身 scala.AnyRef,否则将抛出NullPointerException
对“null”对象的任何其他成员的引用会导致 要引发的NullPointerException


scala中的运算符
==
不同于Java

在scala中,
=
在任何情况下都等同于
equals
方法,
eq
在Java中等同于
=


顺便说一句,为什么null.asInstanceOf[Int]、null.asInstanceOf[Double]、null.asInstanceOf[Boolean]、null.asInstanceOf[Char]不抛出NullPointerException?

但是与
null
相比,有什么区别吗?我可以在这里使用
null==last
吗?谢谢。因此,
val-msg=if(null-eq-last)null
可以替换为
val-msg=if(null==last)null
,但不能替换为
val-msg=if(last==null)null
,对吗?@Freewind我的测试表明
x==null
null==x
分别被视为
x eq-null
。(我认为这是一个编译器优化)。唯一看起来“out”的情况是
x==y
,其中x的计算结果不为null——在这种情况下(仅在这种情况下)调用equals方法。但是,即使在
x==y
x
的计算结果为null时未调用equals,编译器也可能无法生成与
null
作为操作数之一出现时一样高效的字节码,因为它不知道
x
的计算结果为null。再次感谢!因此,我可以为该行代码编写
val msg=if(null==last)null
val msg=if(last==null)null
,“近似等效”。请看我的答案中的例子,它们表明映射并不完全是1-1。考虑发布一个新的问题WRT。代码>安装。由于
Int
“不符合”
AnyRef
,我不确定它为什么不抛出NPE。我有一个问题