Ответ
Ключевое слово late в Dart используется для объявления переменной, инициализация которой будет отложена до момента её первого использования. Оно даёт компилятору гарантию, что к моменту чтения переменная будет проинициализирована, что позволяет использовать non-nullable типы (String, int, CustomClass) там, где значение неизвестно сразу.
Основные причины использования late:
- Отложенная инициализация в конструкторе: Когда значение зависит от вычислений или аргументов, которые становятся известны внутри конструктора, но не могут быть переданы как параметры инициализатора.
- Инициализация в методе
initState: Для полей в StatefulWidget, которые настраиваются при инициализации виджета. - Ленивая инициализация (lazy): Когда переменная инициализируется только при первом обращении к ней, что может быть полезно для тяжеловесных объектов.
Пример 1: Отложенная инициализация
class WeatherService {
late final String _apiKey; // Не инициализирована сразу
WeatherService() {
// Ключ получаем асинхронно или из сложной логики
_apiKey = _fetchApiKeyFromConfig();
}
String _fetchApiKeyFromConfig() => 'some_key';
}
Пример 2: Ленивая инициализация (вычисляется один раз при первом обращении)
class ExpensiveObject {
late final HeavyClass _heavyInstance = HeavyClass();
// _heavyInstance будет создан только при первом вызове getter'а
}
Важное предупреждение: Если прочитать late-переменную до её инициализации, будет выброшено исключение LateInitializationError. Это делает код безопаснее, чем использование nullable-типа (String?), так как ошибка обнаруживается сразу в рантайме, а не приводит к скрытым null.