如果覆盖`hashCode`,覆盖`==`

时间:2020-02-22 06:12:56

标签: flutter dart

我在飞镖课上有以下课程...

class Color {
    final int value;
    const Color._internal(this.value);

    static const Color WHITE = const Color._internal(0);
    static const Color BLACK = const Color._internal(1);

    int get hashCode => value;
    String toString() => (this == WHITE) ? 'w' : 'b';
}

运行flutter分析命令时,出现以下错误...

info•如果覆盖==,则覆盖hashCode•lib / chess.dart:1584:13 •hash_and_equals

作为测试,我添加了方法

bool operator==(Object o) => true;

但是后来我又遇到了一个分析仪问题。...

错误•常量映射条目键表达式类型'Color'不能 覆盖==运算符•lib / chess.dart:44:3• const_map_key_expression_type_implements_equals

这是因为Color对象在静态const映射中用作键...

static const Map<Color, List> PAWN_OFFSETS = const {
    BLACK: const [16, 32, 17, 15],
    WHITE: const [-16, -32, -17, -15]
};

因此,我对于防止这些分析仪问题的选择感到困惑。

如果我删除了hashCode,该类将无法在地图中工作... 如果我添加==运算符,只会得到另一个错误。

什么是最佳选择?

2 个答案:

答案 0 :(得分:1)

问题是 Dart 需要在编译时评估 const Map。由于您有一个用户生成的对象,它不能这样做,因此错误。

您的选择是:

  1. 使您的地图非常量。您可以根据需要使用 bool operator ==(Object o) => true,但适当的样式建议同时覆盖 hashCode 和 ==。
  2. 不要使用覆盖,而是使用 Color.value 来传递 const map

DartPad 中的以下 GIST shows option 1The following issue in Flutter's Github helped me with the answer

答案 1 :(得分:-2)

Map中不能有两个相等的键,并且通过声明:#p>告诉编译器任何Color对象都与任何其他Color对象相等。

bool operator==(Object o) => true;

这样,编译器认为BLACKWHITE是同一件事。但是,如果您改为执行以下操作:

bool operator==(Object o) => o is Color && o.value == value;

如果两个Color对象相等,则编译器将仅认为两个对象相等。因此,它将不再认为valueBLACK相等(因为它们的值不同),因此应该解决该问题。