¿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 tratanulls correctamente. La igualdad de referencia (raramente utilizada) eseq.fuente
3 == BigInt(3)yBigInt(3) == 3son 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
equalsMétodo de anulación para comparar el contenido de cada instancia. Este es el mismoequalsmétodo utilizado en Java==operador para comparar, sin preocuparse por lasnullreferencias.eqmé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 conAnyRefargumentos, no soloAnyNOTA: 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áfalsedonde 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 tipoNumberni deBigInttipo, 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 2regresaráfalse, ya que redirige aInteger.equals(...)1 == 2regresaráfalse, ya que redirige aInteger.equals(...)1 eq 2no se compilará, ya que requiere que ambos argumentos sean de tipoAnyRefnew 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 fooregresarátrue, a menos quefooseanull, luego arrojará unNullPointerExceptionfoo == foovolverátrue, incluso sifooesnullfoo eq foovolverátrue, ya que ambos argumentos enlazan con la misma referenciafuente
Hay una diferencia interesante entre
==yequalsparaFloatyDoubletipos: tratan de maneraNaNdiferente:Editar: como se señaló en un comentario, "esto también sucede en Java", depende de qué es exactamente esto :
Esto imprimirá
Entonces, los
unboxedNanrendimientosfalseen 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
equalscaso, 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
Anyy 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 deNaNvalores primitivos , peroequalsusa 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
NaNusa realmenteisNaN:fuente
En Scala == primero verifique los valores nulos y luego llame al método igual en el primer objeto
fuente