Как переопределить операторы сравнения в Dart?

«Как переопределить операторы сравнения в Dart?» — вопрос из категории Dart Core, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В Dart для переопределения операторов сравнения используется ключевое слово operator. Для оператора == также необходимо переопределить геттер hashCode, чтобы объекты корректно работали в коллекциях типа Set и Map.

Пример переопределения для класса Money:

class Money {
  final int cents;

  Money(this.cents);

  // Переопределение оператора равенства
  @override
  bool operator ==(Object other) {
    return identical(this, other) ||
        other is Money &&
        runtimeType == other.runtimeType &&
        cents == other.cents;
  }

  // Обязательно переопределяем hashCode
  @override
  int get hashCode => cents.hashCode;

  // Переопределение операторов сравнения
  bool operator <(Money other) => cents < other.cents;
  bool operator >(Money other) => cents > other.cents;
  bool operator <=(Money other) => cents <= other.cents;
  bool operator >=(Money other) => cents >= other.cents;
}

void main() {
  final money1 = Money(100);
  final money2 = Money(200);

  print(money1 == Money(100)); // true
  print(money1 < money2);      // true
  print(money1 >= money2);     // false

  // Работа с коллекциями
  final moneySet = {money1, Money(100)};
  print(moneySet.length); // 1, потому что объекты равны
}

Важные моменты:

  1. identical(this, other) — проверка на идентичность (один и тот же объект в памяти)
  2. Проверка типаother is Money && runtimeType == other.runtimeType гарантирует, что сравниваются объекты одного типа
  3. hashCode должен быть согласован с == — если два объекта равны по ==, их хэш-коды должны совпадать