Выбор ответа Middle Dart: типы и null-safety обновлено
Dart: почему не сужается тип публичного поля
Вопрос
Почему в коде ниже компилятор ругается на name.length, хотя есть проверка на null?
class Profile {
String? name;
void show() {
if (name != null) {
print(name.length); // ошибка компиляции
}
}
}
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Поле может оказаться геттером или быть переопределено, второе чтение вправе вернуть null. Сужение (promotion) работает для локальных переменных и, начиная с Dart 3.2, для приватных final-полей.
Варианты ответа
- Поле может оказаться геттером или быть переопределено, второе чтение вправе вернуть
nullправильный ответ - Сужение типа в Dart работает только внутри
switchиif-case, а обычныйifего не даёт - Нужно сравнивать через
identical(name, null): оператор!=не участвует в сужении типа - Ошибки на самом деле нет: Dart сужает тип любых полей класса после проверки на
null
Разбор
Сужение (promotion) работает для локальных переменных и, начиная с Dart 3.2, для приватных final-полей. Обычное поле может оказаться геттером или быть переопределено в подклассе, поэтому два чтения не обязаны совпадать. Решение: скопировать в локальную переменную (final n = name; if (n != null) print(n.length);). Проверка через != в if нормально участвует в сужении, дело не в ней.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.