Ответ
В Dart не существует отдельной конструкции late init. Под этим обычно понимается использование модификатора late для реализации отложенной (deferred) или ленивой (lazy) инициализации non-nullable полей.
Два основных паттерна "late init":
1. Отложенная инициализация (Deferred Initialization)
Значение присваивается явно где-то в коде (в конструкторе, в initState, в методе) до первого чтения.
class ProfileBloc {
late final ProfileRepository _repo; // Объявляем как late
late final StreamController _controller;
ProfileBloc() {
// Инициализируем в конструкторе, но не в списке инициализаторов
_repo = ProfileRepository();
_controller = StreamController.broadcast();
}
void dispose() {
_controller.close(); // Гарантированно инициализировано
}
}
2. Ленивая инициализация (Lazy Initialization) Значение вычисляется и присваивается только в момент первого обращения к полю (getter). Инициализатор выполняется один раз.
class AppSettings {
// _settingsCache будет вычислен только при первом вызове `settings`
late final Map<String, dynamic> _settingsCache = _loadSettingsFromDisk();
Map<String, dynamic> _loadSettingsFromDisk() {
print('Loading settings...'); // Выведется только один раз
// Тяжелая операция чтения файла
return {'theme': 'dark', 'language': 'en'};
}
String get theme => _settingsCache['theme']; // Здесь произойдет инициализация
}
Сравнение с альтернативами:
latevs?(nullable):lateтребует гарантированной инициализации и выбрасывает четкую ошибку при её нарушении.String?требует постоянных проверок наnull.late final: Комбинацияlateсfinalозначает, что после инициализации значение поля изменить нельзя.
Итог: late — это инструмент для работы со строгой null-безопасностью Dart, позволяющий отложить инициализацию, сохраняя гарантии non-nullable типов.