¿Cuál es la diferencia entre ==
y .equals()
en Scala, y cuándo usar cuál?
¿La implementación es la misma que en Java?
EDITAR: La pregunta relacionada se refiere a casos específicos de AnyVal
. El caso más general es Any
.
¿Cuál es la diferencia entre ==
y .equals()
en Scala, y cuándo usar cuál?
¿La implementación es la misma que en Java?
EDITAR: La pregunta relacionada se refiere a casos específicos de AnyVal
. El caso más general es Any
.
Respuestas:
Normalmente se utiliza
==
, se dirige aequals
, excepto que tratanull
s correctamente. La igualdad de referencia (raramente utilizada) eseq
.fuente
3 == BigInt(3)
yBigInt(3) == 3
son verdad. Pero,3.equals(BigInt(3))
es falso, mientras queBigInt(3).equals(3)
es cierto. Por lo tanto, prefiera usar==
. Evite usarequals()
en scala. Creo==
que la conversión implícita funciona bien, peroequals()
no lo hace.new java.lang.Integer(1) == new java.lang.Double(1.0)
es cierto mientras quenew java.lang.Integer(1) equals new java.lang.Double(1.0)
es falso?==
es un método final y llama.equals
, que no es definitivo.Esto es radicalmente diferente de Java, donde
==
es un operador en lugar de un método y compara estrictamente la igualdad de referencia para los objetos.fuente
TL; DR
equals
Método de anulación para comparar el contenido de cada instancia. Este es el mismoequals
método utilizado en Java==
operador para comparar, sin preocuparse por lasnull
referencias.eq
método para verificar si ambos argumentos son EXACTAMENTE la misma referencia. Se recomienda no usar a menos que comprenda cómo funciona esto y, a menudoequals
, funcionará para lo que necesita. Y asegúrese de usar esto solo conAnyRef
argumentos, no soloAny
NOTA: en el caso de
equals
, al igual que en Java, es posible que no devuelva el mismo resultado si cambia los argumentos, por ejemplo1.equals(BigInt(1))
, devolveráfalse
donde regresará el inversotrue
. Esto se debe a que cada implementación verifica solo tipos específicos. Los números primitivos no comprueban si el segundo argumento es de tipoNumber
ni deBigInt
tipo, sino solo de otros tipos primitivosDetalles
El
AnyRef.equals(Any)
método es el anulado por las subclases. Un método de la especificación Java que también se ha introducido en Scala. Si se usa en una instancia sin caja, está en caja para llamar a esto (aunque está oculto en Scala; más obvio en Java conint
->Integer
). La implementación predeterminada simplemente compara referencias (como en Java)El
Any.==(Any)
método compara dos objetos y permite que cualquiera de los argumentos sea nulo (como si se llamara a un método estático con dos instancias). Compara si ambos sonnull
, luego llama alequals(Any)
método en la instancia en caja.El
AnyRef.eq(AnyRef)
método compara solo referencias, que es donde se encuentra la instancia en la memoria. No hay boxeo implícito para este método.Ejemplos
1 equals 2
regresaráfalse
, ya que redirige aInteger.equals(...)
1 == 2
regresaráfalse
, ya que redirige aInteger.equals(...)
1 eq 2
no se compilará, ya que requiere que ambos argumentos sean de tipoAnyRef
new ArrayList() equals new ArrayList()
regresarátrue
, ya que verifica el contenidonew ArrayList() == new ArrayList()
regresarátrue
, ya que redirige aequals(...)
new ArrayList() eq new ArrayList()
regresaráfalse
, ya que ambos argumentos son instancias diferentesfoo equals foo
regresarátrue
, a menos quefoo
seanull
, luego arrojará unNullPointerException
foo == foo
volverátrue
, incluso sifoo
esnull
foo eq foo
volverátrue
, ya que ambos argumentos enlazan con la misma referenciafuente
Hay una diferencia interesante entre
==
yequals
paraFloat
yDouble
tipos: tratan de maneraNaN
diferente:Editar: como se señaló en un comentario, "esto también sucede en Java", depende de qué es exactamente esto :
Esto imprimirá
Entonces, los
unboxedNan
rendimientosfalse
en comparación con la igualdad porque así es como lo definen los números de punto flotante IEEE y esto realmente debería suceder en todos los lenguajes de programación (aunque de alguna manera interfiere con la noción de identidad).El NaN encuadrado rinde verdadero para la comparación usando
==
en Java ya que estamos comparando referencias de objeto.No tengo una explicación para el
equals
caso, en mi humilde opinión, realmente debería comportarse igual que==
en los valores dobles sin caja, pero no lo hace.Traducido a Scala, el asunto es un poco más complicado, ya que Scala ha unificado tipos primitivos y de objetos en
Any
y se traduce en el doble primitivo y el Doble en caja según sea necesario. Por lo tanto, la escala==
aparentemente se reduce a una comparación deNaN
valores primitivos , peroequals
usa el definido en valores dobles en caja (hay mucha magia de conversión implícita y hay cosas que se combinan en doblesRichDouble
).Si realmente necesita saber si algo se
NaN
usa realmenteisNaN
:fuente
En Scala == primero verifique los valores nulos y luego llame al método igual en el primer objeto
fuente