He leído que la construcción de Scala'a case class
genera automáticamente una implementación de montaje equals
y hashCode
. ¿A qué se parece exactamente el código generado?hashCode en las clases de caso en Scala
Respuesta
Como solía decir mi profesor, ¡solo el código dice la verdad! Así que sólo echar un vistazo al código que se genera para:
case class A(i: Int, s: String)
Podemos dar instrucciones al compilador de Scala para mostrarnos el código generado después de las diferentes fases, aquí después de la typechecker:
% scalac -Xprint:typer test.scala
[[syntax trees at end of typer]]// Scala source: test.scala
package <empty> {
@serializable case class A extends java.lang.Object with ScalaObject with Product {
..
override def hashCode(): Int = ScalaRunTime.this._hashCode(A.this);
...
override def equals(x$1: Any): Boolean = A.this.eq(x$1).||(x$1 match {
case (i: Int,s: String)A((i$1 @ _), (s$1 @ _)) if i$1.==(i).&&(s$1.==(s)) => x$1.asInstanceOf[A].canEqual(A.this)
case _ => false
});
override def canEqual(x$1: Any): Boolean = x$1.$isInstanceOf[A]()
};
}
por lo Puede ver que el cálculo del código hash está delegado en ScalaRunTime._hashCode y la igualdad depende de la igualdad de los miembros de la clase de caso.
Esto no solo lo explica bien, sino que me enseñó sobre '-Xprint: typer'. ¡Muchas gracias! Lo único que estoy confundido es ¿qué significa 'ScalaRunTime.this'? ¿Por qué no simplemente 'ScalaRunTime._hashCode'? –
La sintaxis 'ClassName.this' se usa generalmente para acceder a un' this' externo desde dentro de una clase interna (es lo mismo que en Java). No estoy seguro de por qué está impreso aquí, tal vez es la forma en que el código está bastante impreso por el compilador. Pero eso es solo una suposición, ¿alguien más? –
El generada hashCode
sólo llama scala.runtime.ScalaRunTime._hashCode
, que se define como:
def _hashCode(x: Product): Int = {
val arr = x.productArity
var code = arr
var i = 0
while (i < arr) {
val elem = x.productElement(i)
code = code * 41 + (if (elem == null) 0 else elem.hashCode())
i += 1
}
code
}
Así que lo que se obtiene es elem1 * 41**n + elem2 * 41**(n-1) .. elemn * 1
, donde n
es la aridad de su clase de caso y elemi
son los miembros de esa clase caso.
Gracias por la respuesta clara. Ahora no sé si debería aceptar su respuesta o la respuesta de Mirko, de la cual también aprendí el práctico truco '-Xprint: typer' ... –
Juntas, ambas respuestas responden perfectamente a la pregunta :-) –
Tenga en cuenta que las respuestas anteriores a esta pregunta están un poco desactualizadas en la parte hashCode.
A partir de scala 2.9 hashCode
para clases de casos utiliza MurmurHash
: link.
MurmurHash produces good avalanche effect, good distribution and is CPU friendly.
Parece que las cosas han cambiado; usando el ejemplo de Mirko case class A(i: Int, s: String)
me sale: [? ¿Qué código se genera para un método equals/hashCode de una clase caso]
override <synthetic> def hashCode(): Int = {
<synthetic> var acc: Int = -889275714;
acc = scala.runtime.Statics.mix(acc, i);
acc = scala.runtime.Statics.mix(acc, scala.runtime.Statics.anyHash(s));
scala.runtime.Statics.finalizeHash(acc, 2)
};
y
override <synthetic> def equals(x$1: Any): Boolean = A.this.eq(x$1.asInstanceOf[Object]).||(x$1 match {
case (_: A) => true
case _ => false
}.&&({
<synthetic> val A$1: A = x$1.asInstanceOf[A];
A.this.i.==(A$1.i).&&(A.this.s.==(A$1.s)).&&(A$1.canEqual(A.this))
}))
};
- 1. Scala jerarquía de clases caso
- 2. ¿Hay alguna sobrecarga de tiempo o espacio para las clases de casos sobre las clases regulares en Scala?
- 3. preguntas de las clases de scala case
- 4. Clases de casos de Scala en colecciones
- 5. Anulando hashCode en Java para un caso específico
- 6. Clases de Scala en clojure
- 7. Scala contaminación caso objeto
- 8. Scala Caso clase es igual a la implementación
- 9. ¿Es apropiado definir una clase de caso Scala no trivial?
- 10. ¿Se aplican las clases selladas en Java y, en caso afirmativo, cómo?
- 11. ¿Coincide (y vincula) dos clases de excepción en una declaración de caso en Scala 2.7?
- 12. ¿Cómo debo pensar en las clases de productos de Scala?
- 13. Pregunta acerca de las clases de tipo en Scala
- 14. ¿Constructor de sobrecarga para las clases de casos de Scala?
- 15. ¿Debo usar clases anidadas en este caso?
- 16. Modelado con la clase de caso Scala
- 17. referencias de clases avanzadas en Scala?
- 18. Herencia de clase de caso de Scala
- 19. clases internas estáticas en Scala
- 20. clases de iteradores perezosos en Scala?
- 21. ¿Cómo se analiza JSON en Scala usando las clases estándar de Scala?
- 22. Scala - ¿hay suficientes clases?
- 23. Scala - Partido caso cadena parcial
- 24. ¿Por qué se desaprobaron las clases de caso sin una lista de parámetros?
- 25. clases de casos con campos opcionales en Scala
- 26. En Scala, ¿hay alguna manera fácil de convertir una clase de caso en una tupla?
- 27. sobrecarga de métodos cancelar la aplicación en las clases de casos: Scala
- 28. estrategias de aplicación hashCode
- 29. cargadores de clases Scala confusión
- 30. Para iguales y hashcode o no en clases de entidad, esa es la pregunta
posible duplicado de (http://stackoverflow.com/ preguntas/4526706/what-code-is-generated-for-an-equals-hashcode-method-of-a-case-class) – Suma