¿Qué es una buena receta para anular el código hash en Dart?
hashcode (3)
Dado que Dart es tan similar a Java, seguramente puede encontrar buenas referencias en códigos hash para Java que también son aplicables a Dart.
Un poco de Google me llevó a la página de Wikipedia en Object.hashCode()
Java . Tiene un ejemplo muy básico para el código hash de un objeto simple. Una metodología popular es realizar una multiplicación con un número primo (diferentes) y agregar algún valor para cada propiedad del objeto.
Esta pregunta fe explica por qué se elige el número 31 para la multiplicación del método String.hashCode()
.
Se pueden encontrar ejemplos más detallados de implementaciones de hashcode usando Google.
Me encuentro con ganas de anular el código hash y == para un objeto, y me pregunto si hay mejores prácticas para implementar un código hash que dependa de múltiples atributos, y parece que hay algunas consideraciones específicas de Dart.
La respuesta más simple sería para XOR los hashes de todos los atributos juntos, y probablemente no sea tan malo. También hay un ejemplo en Dart Up and Running en https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
// Override hashCode using strategy from Effective Java, Chapter 11.
int get hashCode {
int result = 17;
result = 37 * result + firstName.hashCode;
result = 37 * result + lastName.hashCode;
return result;
}
pero eso parece que espera truncar la semántica de enteros y en Dart desbordar el rango de enteros JS parece malo para el hashing.
También podríamos hacer eso y simplemente truncar a 32 bits después de cada operación.
Para mi aplicación, el tamaño esperado del conjunto es muy pequeño y casi cualquier cosa lo haría, pero me sorprende no ver una receta estándar para el caso general. ¿Alguien tiene alguna experiencia o experiencia fuerte con esto?
El paquete quiver proporciona funciones de ayuda hash2
, hash3
, etc., que simplifican la tarea de implementar hashCode
, con cierta seguridad de que funciona correctamente en la máquina virtual Dart y cuando se compila en JavaScript.
import ''package:quiver/core.dart'';
class Person {
String name;
int age;
Person(this.name, this.age);
bool operator ==(o) => o is Person && name == o.name && age == o.age;
int get hashCode => hash2(name.hashCode, age.hashCode);
}
También vea este post para una discusión un poco más larga.
Si bien no es una gran respuesta, hay un error abierto para proporcionar esto en https://code.google.com/p/dart/issues/detail?id=11617 y el "hash de Jenkins SMI" mencionado allí parece Sé lo mejor que puedes usar si se pone a disposición del público.