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.