2011-08-14 18 views
7

veo en la clase incorporada MessageQueue.scala de Scala 2.7.7, alrededor de la línea 164, que es:¿Cuál es la diferencia entre `null == last` y` null eq last`, en Scala?

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

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

No entiendo val msg = if (null eq last) null así, ¿por qué se utiliza eq, pero no null. Si escribo if (last==null) null, ¿es correcto? Hay alguna diferencia?

+0

Pero, para comparar con 'null', ¿hay alguna diferencia? ¿Puedo usar 'null == last' aquí? – Freewind

Respuesta

13

Cuando ambos lados de la ==esnullo si el primer operando de ==evalúa como nulo, Scala no invocar equals. Entonces, en este caso, sí, x == null es lo mismo que x eq null; el método equals es no invocado. Presta atención a los casos a continuación.

Considera:

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 

y observe que:

(new X()) == null 

resultados en una advertencia diciendo un "un objeto fresca" nunca será igual (a null).

Sospecho que puede haber un código ligeramente más/diferente emitido para x == y que x == null (en caso de que los iguales se deben invocar), pero no se han verificado.

Happy coding.


Sección 6.3 (el valor nulo) de la especificación del lenguaje Scala tiene esto que decir:

El valor nulo es de tipo scala.Null, y es por tanto compatible con todas las referencias tipo. Denota un valor de referencia que se refiere a un objeto especial "nulo". Este objeto implementa métodos en scala.AnyRef clase como sigue:

  • [nulo] eq (x) y [nulo] == (x) devolver verdadero si y sólo si el argumento x es también el objeto “nulo”.
  • ne (x) y! = (X) devuelve verdadero si el argumento x no es también el objeto "nulo".
  • isInstanceOf [T] siempre devuelve falso.
  • asInstanceOf [T] devuelve el objeto "nulo" si T cumple con scala.AnyRef, y arroja una excepción NullPointerException en caso contrario.

Una referencia a cualquier otro miembro del objeto "nulo" provoca que se genere una NullPointerException.

+0

gracias. Entonces, 'val msg = if (null eq last) null' puede ser reemplazado por' val msg = if (null == last) null', pero no 'val msg = if (last == null) null', ¿verdad? – Freewind

+0

@Freewind Mi prueba indica que 'x == null' y' null == x' se tratan como 'x eq null' y' null eq x', respectivamente. (Creo que como una optimización del compilador). El único caso que parece "fuera" es 'x == y', donde x * no * evalúa como nulo, en ese caso (y solo en ese caso) se invoca el método equals. Sin embargo, incluso si equals es * no invocado * cuando 'x' se evalúa como nulo en' x == y', el compilador puede no ser capaz de generar un bytecode tan eficiente como cuando 'null' aparece como uno de los operandos porque no lo hace 't sabe que 'x' evaluará nulo. –

+0

¡Gracias de nuevo! Entonces, puedo escribir ambos 'val msg = if (null == last) null' y' val msg = if (last == null) null' para esa línea de código. – Freewind

0

El operador == en Scala es diferente de Java.

en Scala, == es equivant a equals método en cualquier, eq es equivant a == en Java

Por cierto, ¿por qué no null.asInstanceOf [Int], null.asInstanceOf [doble], null.asInstanceOf [Boolean], null.asInstanceOf [Char] throw NullPointerException?

+0

"Aproximadamente equivalente". Ver los casos en mi respuesta que muestran que el mapeo no es completamente 1-1. Considera publicar una * nueva * pregunta, wrt. 'asInstanceOf'. Como 'Int'" no se ajusta a "' AnyRef', no estoy seguro de por qué no lanza un NPE. –

+0

He posteado una pregunta http://stackoverflow.com/questions/8285916/why-doesnt-null-asinstanceofint-throw-a-nullpointerexception –

Cuestiones relacionadas