在 Dart 中覆盖哈希码的好方法是什么?
我发现自己想要覆盖对象的 hashcode 和 ==,我想知道是否有最佳实践来实现取决于多个属性的 hashcode,而且似乎有一些 Dart 特定的注意事项.
I find myself wanting to override hashcode and == for an object, and I'm wondering if there are best practices for how to implement a hashcode that depends on multiple attributes, and it seems like there are some Dart-specific considerations.
最简单的答案是将所有属性的哈希值异或在一起,这可能还不错.在 https://www.dartlang.org/docs/dart-up-and-running/contents/ch03.html
The simplest answer would be to XOR the hashes of all the attributes together, and it's probably not too bad. There's also an example in Dart Up and 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 整数的范围溢出似乎不利于散列.
but that seems like it expects truncating integer semantics and in Dart overflowing the range of JS integers seems bad for hashing.
我们也可以这样做,并在每次操作后截断为 32 位.
We could also do that and just truncate to 32 bits after each operation.
对于我的应用程序,集合的预期大小非常小,几乎可以做任何事情,但我很惊讶没有看到适用于一般情况的标准配方.有没有人有这方面的经验或丰富的经验?
For my application the expected size of the set is very small and almost anything would do, but I'm surprised not to see a standard recipe for the general case. Does anyone have any experience or strong experience with this?
quiver 包提供了hash2
、hash3
等辅助函数,简化了hashCode
的实现任务,保证了它的正常工作在 Dart VM 下和编译为 JavaScript 时.
The quiver package provides helper functions hash2
, hash3
, etc., which simplify the task of implementing hashCode
, with some assurance that it works properly under the Dart VM and when compiled to 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);
}
另见这篇文章稍长的讨论.