Dart 3.12 избавляет от списка инициализации для приватных полей
Dart 3.12 позволяет конструкторам инициализировать приватные поля напрямую через именованные параметры, устраняя один из самых стойких шаблонных паттернов языка.
Dart 3.12 вышел на Google I/O 2026 вместе с Flutter 3.44, и в этом релизе спрятано небольшое изменение языка, которое убирает кусок шаблонного кода, написанный каждым Dart-разработчиком сотню раз. Теперь приватные именованные параметры можно использовать как initializing formals. Проще говоря: конструктор может принять именованный аргумент и присвоить его напрямую приватному полю, без списка инициализации.
Проблема подчёркивания, которую Dart тащил годами
Dart помечает поле как приватное, добавляя перед ним подчёркивание. Это соглашение вступало в конфликт с именованными параметрами конструктора, потому что язык не позволял именованному параметру начинаться с _. Результатом был знакомый танец: принять параметр с публичным именем, а затем вручную скопировать его в приватное поле в списке инициализации.
class Hummingbird {
final String _petName;
final int _wingbeatsPerSecond;
Hummingbird({required String petName, required int wingbeatsPerSecond})
: _petName = petName,
_wingbeatsPerSecond = wingbeatsPerSecond;
}
Каждое приватное поле означало объявление параметра плюс запись в инициализации. Для класса с восемью приватными полями это шестнадцать строк чистой обвязки. Initializing formals (this.field) решили это для публичных полей много лет назад, но приватные поля остались на медленном пути.
Что на самом деле меняет 3.12
Dart 3.12 заставляет очевидное работать. Напишите this._field как именованный параметр, и компилятор сделает всё остальное:
class Hummingbird {
final String _petName;
final int _wingbeatsPerSecond;
Hummingbird({required this._petName, required this._wingbeatsPerSecond});
}
Поле остаётся приватным, но имя параметра, видимое вызывающей стороне, это публичная версия без подчёркивания. Поэтому место вызова читается точно так же, как раньше:
void main() {
print(Hummingbird(petName: 'Dash', wingbeatsPerSecond: 75));
}
Это изменение исключительно на стороне конструктора. Публичный API идентичен, вызывающая сторона ничего не трогает, а приватные поля остаются приватными. Вы просто удаляете список инициализации, и не более того.
Ограничения, которые стоит знать
Это исключение применимо только к initializing formals. Обычный именованный параметр по-прежнему не может начинаться с подчёркивания, потому что это просочило бы приватное имя в публичную сигнатуру без публичного имени, на которое можно опереться. Имя с подчёркиванием также должно соответствовать допустимому публичному идентификатору: this._ и this._2x отклоняются, потому что после удаления подчёркивания остаётся “ и 2x, ни одно из которых не является допустимым именем параметра.
Эта возможность также сочетается с primary constructors, которые появились как эксперимент в том же цикле и требуют версии языка не ниже 3.13. С обоими в работе вы можете объявить приватное поле прямо в заголовке конструктора и позволить компилятору автоматически опубликовать имя для внешней стороны.
Если вы уже на Flutter 3.44, у вас есть Dart 3.12, и вы можете использовать это сегодня. Поднимите ограничение SDK в вашем pubspec.yaml до ^3.12.0, выполните dart fix и начинайте удалять списки инициализации. Полные примечания к выпуску смотрите в анонсе Dart 3.12.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.