我发现自己想要覆盖一个对象的哈希码和==,我想知道是否有关于如何实现依赖于多个属性的哈希码的最佳实践,并且似乎有一些特定于Dart的注意事项.
最简单的答案是将所有属性的哈希值混合在一起,这可能不是太糟糕.在Dart Up和Running中也有一个例子,网址是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;
}
Run Code Online (Sandbox Code Playgroud)
但似乎它期望截断整数语义,并且在Dart中溢出JS整数的范围似乎不适合散列.
我们也可以这样做,并在每次操作后截断为32位.
对于我的应用程序,预期的集合大小非常小,几乎任何事情都可以,但我很惊讶没有看到一般情况的标准配方.有没有人有这方面的经验或经验?
man*_*nta 81
从 2.14 版本开始,Dart 语言添加了对Object.hash(), 以及Object.hashAll()和 的支持Object.hashAllUnordered()
hash()文档:
为多个对象创建组合哈希码。
例子:
class SomeObject {
final Object a, b, c;
SomeObject(this.a, this.b, this.c);
bool operator==(Object other) =>
other is SomeObject && a == other.a && b == other.b && c == other.c;
int get hashCode => Object.hash(a, b, c); // <----- here
}
Run Code Online (Sandbox Code Playgroud)
文档关于实施的注释:
不能保证此函数生成的哈希值在同一程序的不同运行中或在同一程序的不同隔离区中运行的代码之间保持稳定。所使用的确切算法可能在不同平台之间或不同版本的平台库之间有所不同,并且可能取决于每次程序执行时更改的值。
Pat*_*lin 29
该颤动包提供了辅助功能hash2,hash3等等,这简化了实现的任务hashCode,一些保证其正常运行下达特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);
}
Run Code Online (Sandbox Code Playgroud)
另请参阅此帖子以进行稍微冗长的讨论.
Pav*_*vel 17
该equatable包可以帮助
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
final int age;
Person(this.name, this.age);
@override
List<Object> get props => [name, age];
}
Run Code Online (Sandbox Code Playgroud)
现在 Person 将使用Equatable 中的==和hashCode,它需要props您提供的列表
Dan*_*ton 17
为了最小化依赖关系,如果您已经依赖 flutter,但不依赖于类似的东西quiver, dart:ui库包含实用程序,hashValues以及hashList用于创建和组合哈希值。如果组合列表值,必须小心确保相等运算符和哈希码匹配行为。如果哈希码计算它的哈希值很深,则使用深度相等,否则使用浅相等。
class Example {
final String value1;
final Object value2;
final List<Object> deep;
final List<Object> shallow;
Example({this.value1, this.value2, this.deep, this.shallow});
@override
operator ==(o) =>
o is Example &&
o.value1 == value1 &&
o.value2 == value2 &&
listEquals(o.deep, deep) &&
o.shallow == shallow;
@override
int get hashCode => hashValues(value1, value2, hashList(deep), shallow);
}
Run Code Online (Sandbox Code Playgroud)
Joa*_*ido 11
我推荐“等效”插件
https://pub.dev/packages/equatable
例子:
原始模式:
class Person {
final String name;
const Person(this.name);
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
runtimeType == other.runtimeType &&
name == other.name;
@override
int get hashCode => name.hashCode;
}
Run Code Online (Sandbox Code Playgroud)
与等同:
import 'package:equatable/equatable.dart';
class Person extends Equatable {
final String name;
Person(this.name);
@override
List<Object> get props => [name];
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5645 次 |
| 最近记录: |