【问题标题】:Override `==` if overriding `hashCode`如果覆盖 `hashCode`,则覆盖 `==`
【发布时间】:2020-06-06 12:38:58
【问题描述】:

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

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';
}

当我运行颤振分析命令时,我收到以下错误...

信息 • 覆盖== 如果覆盖hashCode • lib/chess.dart:1584:13 • hash_and_equals

作为测试,我添加了方法

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

但后来我遇到了另一个分析器问题....

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

这是因为 Color 对象被用作静态常量映射中的键...

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

所以我对如何防止这些分析器问题感到困惑。

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

什么是最好的选择?

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

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

    您的选择是:

    1. 使您的地图非常量。如果您愿意,可以使用 bool operator ==(Object o) =&gt; true,但正确的样式建议同时覆盖 hashCode 和 ==。
    2. 不要使用覆盖,而是使用 Color.value 来传递 const map。

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

    【讨论】:

      【解决方案2】:

      Map 中不能有两个相等的键,并且您告诉编译器任何 Color 对象都等于任何其他 Color 对象,方法是:

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

      这样,编译器认为BLACK 和WHITE 是同一个东西。但是,如果您改为这样做:

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

      如果两个Color 对象的values 相等,编译器只会认为它们相等。因此,它不会认为BLACK和WHITE不再相等(因为它们的值不同),应该解决这个问题。

      【讨论】:

      • 这根本不能回答问题。返回 true 只是一个临时的测试方法定义......你读过这个问题吗?
      • 不完全正确。如果映射不是 const,编译器将使用 value 来散列。如果映射为 const,则用户定义的对象无论如何都不会编译。但是,最好进行适当的覆盖。
      猜你喜欢
      • 2018-03-27
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多