Start Debugging

Dart 3.12 добавляет первичные конструкторы за экспериментальным флагом

Dart 3.12 добавляет экспериментальный синтаксис первичных конструкторов, который объявляет поля и конструктор в заголовке класса, сокращая классический трёхстрочный класс данных до одной строки.

В Dart 3.12 (выпущен 2026-05-20) появилась одна из самых востребованных возможностей языка в виде экспериментальной предварительной версии: первичные конструкторы. Если вы когда-нибудь писали одно и то же поле, плюс параметр конструктора this.field, плюс присваивание трижды для простого класса данных, то это тот синтаксис, который устраняет этот шаблон. Пока он доступен за --enable-experiment=primary-constructors, но уже сегодня стоит подключить его в отдельной ветке, потому что он меняет то, как читается значительная часть повседневного кода на Dart.

Это продолжает другое сокращение шаблонного кода в Dart 3.12, приватные именованные параметры как инициализирующие формальные параметры. Первичные конструкторы идут дальше: они переносят всё объявление в заголовок класса.

Одна строка вместо четырёх

Вот класс данных, который пишут все, та часть, которую компилятор должен был генерировать с самого начала:

class Point {
  final int x;
  final int y;
  Point(this.x, this.y);
}

С первичным конструктором объявления полей и конструктор сворачиваются в заголовок. Пустое тело класса превращается в точку с запятой:

class Point(final int x, final int y);

Правило простое: параметр, помеченный final или var в заголовке, становится полем экземпляра. Уберите модификатор, и он останется обычным параметром конструктора, а не полем. Так, class User(String name); принимает name как аргумент, не сохраняя его, тогда как class User(final String name); сохраняет его.

Поля могут зависеть от параметров заголовка

Параметры заголовка находятся в области видимости внутри тела класса, поэтому вы можете инициализировать другие не-late поля на их основе без списка инициализации:

class DeltaPoint(final int x, int delta) {
  final int y = x + delta;
}

Здесь delta это параметр конструктора (без final, поэтому не поле), а y вычисляется на его основе.

Добавление проверки с телом

Когда вам нужен assert или какая-то настройка, вы пишете тело конструктора, вводимое через this. Форма только со списком инициализации заканчивается точкой с запятой:

class Point(var int x, var int y) {
  this : assert(x >= 0 && y >= 0) {
    print('Point initialized at ($x, $y)');
  }
}

Именованные конструкторы тоже получают более компактную форму, используя new в теле:

class Pet {
  String name;

  new() : name = 'Fluffy';
  new withName(this.name);
}

Как включить

Возможность экспериментальная, поэтому вы включаете её для каждого запуска:

dart run --enable-experiment=primary-constructors bin/main.dart

Поскольку она экспериментальная, относитесь к ней как к предварительной версии: синтаксис ещё может измениться до стабилизации, а final и var теперь несут особое значение в списке параметров, поэтому пока не переносите её в общий продакшен-код. Но для отдельной ветки первичные конструкторы делают заметно короче модели виджетов Flutter, объекты-значения и контейнеры конфигурации. Полную спецификацию, включая super-параметры и правила именованных конструкторов, смотрите в документации Dart по первичным конструкторам.

Comments

Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.

< Назад