Что такое оператор двойного равно (==) в Dart?

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

Ответ

Оператор == (двойное равно) в Dart — это оператор проверки равенства значений (эквивалентности) объектов. Он сравнивает содержимое объектов, а не их идентичность в памяти (для сравнения ссылок используется функция identical()).

Как работает по умолчанию: Для экземпляров классов (не примитивов) оператор == по умолчанию сравнивает ссылки. Это означает, что два разных объекта с одинаковыми полями будут считаться неравными.

void main() {
  var list1 = [1, 2];
  var list2 = [1, 2];
  var list3 = list1;

  print(list1 == list2); // false (разные экземпляры в памяти)
  print(identical(list1, list2)); // false
  print(list1 == list3); // true (одна и та же ссылка)
  print(identical(list1, list3)); // true

  // Для примитивов (int, String, bool) == сравнивает значения
  var a = 'hello';
  var b = 'hello';
  print(a == b); // true (значения одинаковы, строка интернирована)
}

Переопределение оператора == для своих классов: Чтобы сравнение работало по значению полей, необходимо переопределить оператор == и метод hashCode. Это критически важно для корректной работы с коллекциями (Set, Map).

class Person {
  final String name;
  final int age;

  Person(this.name, this.age);

  @override
  bool operator ==(Object other) {
    // Проверяем идентичность, тип и сравниваем поля
    return identical(this, other) ||
        other is Person &&
        runtimeType == other.runtimeType &&
        name == other.name &&
        age == other.age;
  }

  @override
  int get hashCode => Object.hash(name, age); // Генерация хэш-кода на основе полей
}

void main() {
  var p1 = Person('Alice', 30);
  var p2 = Person('Alice', 30);
  var p3 = Person('Bob', 25);

  print(p1 == p2); // true (поля одинаковы)
  print(p1 == p3); // false

  var personSet = {p1};
  print(personSet.contains(p2)); // true (благодаря правильным == и hashCode)
}

Null-безопасность: Оператор == не защищает от null. Для безопасного сравнения с null используйте object == null или оператор ?.

String? nullableString;
print(nullableString == null); // true
print(nullableString?.isEmpty ?? true); // Безопасный доступ с проверкой на null