2011-08-14 97 views
7

我看到斯卡拉2.7.7的內置MessageQueue.scala類,圍繞線164,它是:在Scala中`null == last`和`null eq last`有什麼區別?

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,它是正確的嗎?有什麼區別嗎?

+0

但是與'null'比較,有沒有區別?我可以在這裏使用'null == last'嗎? – Freewind

回答

13

當的==任一側是null如果==第一個操作數的計算結果爲空,那麼Scala中不會調用equals。那麼,在這種情況下,是的,x == nullx 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,並且因此與每個引用 兼容類型。它表示一個引用一個特殊的「空」對象的引用值。該目的 實現類scala.AnyRef方法如下:

  • [空]當量(x)和[空] ==(x)的返回當且僅當自變量x真也是「空」對象。
  • ne(x)和!=(x)如果參數x不是「null」對象,則返回true。
  • isInstanceOf [T]總是返回false。
  • asInstanceOf [T]返回「null」對象本身,如果T符合 scala.AnyRef,否則拋出NullPointerException。

對「null」對象的任何其他成員的引用會導致引發NullPointerException 。

+0

謝謝。所以,'val msg = if(null eq last)null'可以用'val msg = if(null == last)null'替換,而不是'val msg = if(last == null)null',對嗎? – Freewind

+0

@Freewind我的測試表明'x == null'和'null == x'分別被當作'x eq null'和'null eq x'。 (我相信作爲編譯器優化)。唯一出現「out」的情況是'x == y',其中x *沒有*評估爲null - 在這種情況下(只有這種情況)纔會調用equals方法。但是,即使equals在* x中沒有被調用,當'x =='中的x值爲空時,編譯器可能無法生成與'null'作爲操作數之一一樣有效的字節碼,因爲它不會不知道'x'會評估爲null。 – 2011-08-14 06:40:22

+0

再次感謝您!所以,我可以爲該行代碼寫入'val msg = if(null == last)null'和'val msg = if(last == null)null'。 – Freewind

0

scala中的運算符==與Java的不同。

在Scala中,==是equivant在任何equals方法,eq是equivant到==在Java中

BTW,爲什麼不null.asInstanceOf [INT],null.asInstanceOf [雙],null.asInstanceOf [布爾],null.asInstanceOf [Char]拋出NullPointerException?

+0

「大致相當」。查看我的答案中顯示映射不完全是1-1的情況。考慮發佈*新問題。 'asInstanceOf'。由於'Int'「不符合」AnyRef「,我不確定它爲什麼不拋出NPE。 – 2011-08-14 16:42:03

+0

我有一個問題http://stackoverflow.com/questions/8285916/why-doesnt-null-asinstanceofint-throw-a-nullpointerexception –

相關問題