Подтвердить что ты не робот

Какой хороший рецепт для переопределения hashcode в Dart?

Я нахожусь в том, что хочу переопределить hashcode и == для объекта, и мне интересно, есть ли лучшие методы для реализации хэш-кода, который зависит от нескольких атрибутов, и кажется, что есть некоторые особенности, связанные с Дартом.

Простейшим ответом будет XOR хэши всех атрибутов вместе, и это, вероятно, не так уж плохо. Также есть пример в Dart Up и Running at 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;
 }

но похоже, что он ожидает усечения целочисленной семантики и в Dart, переполняющем диапазон JS-целых чисел, кажется плохой для хэширования.

Мы могли бы это сделать и просто усекать до 32 бит после каждой операции.

Для моего приложения ожидаемый размер набора очень мал и почти ничего не будет, но я удивлен, что не вижу стандартный рецепт для общего случая. Кто-нибудь имеет опыт или сильный опыт в этом?

4b9b3361

Ответ 1

колчан пакет предоставляет вспомогательные функции hash2, hash3 и т.д., которые упрощают задачу реализации hashCode, с некоторой уверенностью, что он работает правильно под Dart VM и при компиляции на 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);
}

Также см. этот пост для обсуждения немного длиннее.

Ответ 2

Так как Dart настолько похож на Java, вы наверняка найдете хорошие ссылки на hashCodes для Java, которые применимы и для Dart.

Маленький поисковик взял меня на страницу Wikipedia на Java Object.hashCode(). Имеет очень простой пример для хэш-кода простого объекта. Популярной методологией является выполнение умножения с простым числом (разные) и добавление некоторого значения для каждого свойства объекта.

Этот вопрос f.e. объясняет, почему число 31 выбрано для умножения для метода String.hashCode().

Более подробные примеры реализации хэш-кода можно легко найти с помощью Google.

Ответ 3

В то время как это не очень хороший ответ, есть открытая ошибка для обеспечения этого в https://code.google.com/p/dart/issues/detail?id=11617 и "хэши Jenkins SMI", на которые они ссылаются похоже, было бы лучше всего использовать, если бы оно было общедоступным.