Как работают константные конструкторы (const constructors) в Dart?

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

Ответ

Константные конструкторы в Dart — это механизм для создания канонизированных (canonicalized), неизменяемых объектов во время компиляции. Это оптимизация как для производительности, так и для дизайна неизменяемых классов.

Основные правила:

  • Все поля класса должны быть объявлены как final.
  • Конструктор объявляется с ключевым словом const.
  • Тело конструктора должно быть пустым (используется только инициализирующий список :, если нужна логика).
  • Параметры могут быть только константными выражениями при создании экземпляра с const.

Пример и преимущество канонизации:

class ConstColor {
  final int r, g, b;
  const ConstColor(this.r, this.g, this.b);

  @override
  String toString() => 'Color($r, $g, $b)';
}

void main() {
  // Создание с 'const' — объекты создаются на этапе компиляции
  const color1 = ConstColor(255, 0, 0);
  const color2 = ConstColor(255, 0, 0);

  print(identical(color1, color2)); // true! Это один и тот же объект в памяти.

  // Создание БЕЗ 'const' — каждый раз новый объект
  var color3 = ConstColor(255, 0, 0);
  var color4 = ConstColor(255, 0, 0);
  print(identical(color3, color4)); // false
}

Где я это использую в Flutter: Flutter широко использует эту концепцию для оптимизации. Виджеты, созданные с const, не перестраиваются при ребилде дерева, если их входные данные не изменились.

// Хорошо: Const-виджет создается один раз
@override
Widget build(BuildContext context) {
  return const Padding(
    padding: EdgeInsets.all(16.0), // EdgeInsets.all тоже const конструктор
    child: Text('Hello'),
  );
}
// Плохо: Каждый build создает новые объекты Padding и EdgeInsets
@override
Widget build(BuildContext context) {
  return Padding(
    padding: EdgeInsets.all(16.0), // Создается новый объект каждый раз
    child: Text('Hello'),
  );
}

Использование const конструкторов для простых моделей данных и виджетов — это best practice для повышения производительности Flutter-приложения.