В чем разница final и const в Dart
Что проверяют
Понимаете ли вы разницу между «переменную нельзя переназначить» и «значение известно при компиляции и неизменяемо целиком». Dart во фронтенде это прежде всего Flutter, включая Flutter Web, поэтому следом почти всегда спрашивают, зачем ставить const перед виджетами.
Как отвечать
final: переменной присваивают значение один раз, но вычислить его можно в рантайме:final now = DateTime.now();. Сам объект при этом может быть изменяемым:final list = [1, 2]; list.add(3);работает, запрещено толькоlist = [...];const: значение должно быть константой времени компиляции и неизменяемо глубоко.const list = [1, 2]; list.add(3);компилируется, но в рантайме броситUnsupportedError;- канонизация: одинаковые
const-выражения сводятся к одному экземпляру.identical(const [1, 2], const [1, 2])вернётtrue; constу значения и у переменной: вvar items = const [1, 2];переменную можно переназначить, а сам список неизменяем;- поля класса:
constбывает толькоstatic const, для полей экземпляра используютfinal. Если все поляfinal, у класса можно объявитьconst-конструктор; late final: присвоение один раз, но позже объявления, например вinitState.
Практический смысл во Flutter: const Text('Заголовок') или const SizedBox(height: 16) создаются один раз. Когда родитель перестраивается, фреймворк получает тот же экземпляр виджета и не обновляет это поддерево. Отсюда линт prefer_const_constructors. Внутри константного контекста, например в const [...] или в аргументах const-конструктора, повторять const у вложенных значений не нужно.
Где спотыкаются
Считают final полностью неизменяемым. Неизменяема ссылка, а содержимое списка или объекта менять можно.
Объясняют выгоду const тем, что он «компилируется в байткод и поэтому быстрее». Выгода в канонизации: объект создаётся на этапе компиляции, не аллоцируется заново и позволяет Flutter пропускать перестройку.
Пытаются сделать const из того, что зависит от рантайма: const now = DateTime.now(); или const-виджет с параметром из State. Это ошибка компиляции, здесь нужен final.