2011-08-14 33 views
7

tôi thấy trong các built-in Class MessageQueue.scala của scala 2.7.7, xung quanh dòng 164, đó là:Sự khác biệt giữa `null == last` và` null eq last`, trong Scala là gì?

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

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

Tôi không hiểu val msg = if (null eq last) null tốt, tại sao nó sử dụng eq, nhưng không null. Nếu tôi viết if (last==null) null, có đúng không? Có sự khác biệt nào không?

+0

Nhưng để so sánh với 'null', có sự khác biệt nào không? Tôi có thể sử dụng 'null == last' ở đây không? – Freewind

Trả lời

13

Khi một trong hai bên của ==nullhoặc nếu toán hạng đầu tiên của ==đánh giá để null, sau đó Scala sẽ không gọi equals. Vì vậy, trong trường hợp này, có, x == null giống như x eq null; phương pháp equalskhông phải là được gọi. Chú ý đến các trường hợp dưới đây.

Hãy xem xét điều này:

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 

Và lưu ý rằng:

(new X()) == null 

Kết quả trong một cảnh báo nói rằng một "một đối tượng tươi" sẽ không bao giờ bằng nhau (để null).

Tôi nghi ngờ có thể có nhiều hơn một chút/mã khác được phát ra cho x == y hơn x == null (trong trường hợp phải bằng lệnh), nhưng chưa được kiểm tra.

Mã hóa vui vẻ.


Mục 6.3 (The Null Value) của Scala Language Specification đã cho biết:

Giá trị null là loại scala.Null, và do đó tương thích với tất cả các tài liệu tham khảo kiểu. Nó biểu thị một giá trị tham chiếu liên quan đến một đối tượng “null” đặc biệt. Đây đối tượng thực hiện phương pháp trong lớp scala.AnyRef như sau:

  • [null] eq (x) và [null] == (x) trả về true khi và chỉ khi tham số x cũng là đối tượng “vô giá trị”.
  • ne (x) và! = (X) trả về true iff đối số x cũng không phải là đối tượng “rỗng”.
  • isInstanceOf [T] luôn trả về false.
  • asInstanceOf [T] trả về đối tượng “rỗng” nếu T tuân theo scala.AnyRef và ném NullPointerException theo cách khác.

Tham chiếu đến bất kỳ thành viên nào khác của đối tượng “rỗng” sẽ gây ra một lỗi NullPointerException.

+0

cảm ơn bạn. Vì vậy, 'val msg = if (null eq last) null' có thể được thay thế bằng' val msg = if (null == last) null', nhưng không phải 'val msg = if (last == null) null', phải không? – Freewind

+0

@Freewind Thử nghiệm của tôi chỉ ra rằng 'x == null' và' null == x' được coi là 'x eq null' và' null eq x', tương ứng. (Tôi tin là tối ưu hóa trình biên dịch). Trường hợp duy nhất có vẻ "out" là 'x == y', trong đó x * không * đánh giá null - trong trường hợp đó (và chỉ trường hợp đó) phương thức equals được gọi. Tuy nhiên, ngay cả khi equals là * not invoked * khi 'x' đánh giá null trong' x == y', trình biên dịch có thể không có khả năng tạo ra bytecode hiệu quả như khi 'null' xuất hiện như một toán hạng vì nó không Không biết rằng 'x' sẽ đánh giá là null. –

+0

Cảm ơn bạn một lần nữa! Vì vậy, tôi có thể viết cả hai 'val msg = if (null == last) null' và' val msg = if (last == null) null' cho dòng mã đó. – Freewind

0

Nhà điều hành == trong scala khác với Java.

Trong scala, == là equivant để equals phương pháp trong Bất kỳ, eq là equivant để == trong Java

BTW, tại sao không null.asInstanceOf [Int], null.asInstanceOf [đúp], null.asInstanceOf [Boolean], null.asInstanceOf [Char] ném NullPointerException?

+0

"Khoảng tương đương". Xem các trường hợp trong câu trả lời của tôi cho thấy bản đồ không hoàn toàn là 1-1. Xem xét đăng một câu hỏi * mới * wrt. 'asInstanceOf'. Vì 'Int'" không phù hợp với "' AnyRef', tôi không chắc tại sao nó không ném NPE. –

+0

Tôi đã đăng câu hỏi http://stackoverflow.com/questions/8285916/why-doesnt-null-asinstanceofint-throw-a-nullpointerexception –

Các vấn đề liên quan