Почему в Dart 2.10 было принято решение отказаться от неявного приведения типов?
Sobes Copilot
Get answers in real time
Answer from AI
sobes.tech AI
В Dart 2.10 отказ от неявного приведения типов (implicit downcasting) был обусловлен несколькими ключевыми причинами:
-
Улучшение безопасности кода: Неявное приведение типов могло приводить к ошибкам времени выполнения (runtime errors), которые было сложно отладить. Например, попытка обращения к методу, который отсутствует в фактическом типе объекта, но присутствовал в предсказанном статическом типе. Явное приведение типов (explicit casting) делает такие потенциальные ошибки видимыми на этапе компиляции или времени выполнения с более явным указанием проблемы.
-
Повышение предсказуемости: Код с явным приведением типов более предсказуем, так как разработчик явно указывает, какого типа он ожидает объект. Это упрощает чтение и понимание кода.
-
Подготовка к Sound Null Safety: Удаление неявного приведения типов стало важным шагом на пути к внедрению Sound Null Safety в Dart 2.12. Sound Null Safety гарантирует, что ссылки не могут содержать
nullбез явного на то указания. Неявное приведение типов могло нарушить эти гарантии, так как типизация становилась менее строгой.
Рассмотрим пример:
// До Dart 2.10
void processList(List<int> list) {
// В старых версиях Dart:
// Если actualList на самом деле List<dynamic> с не-числовыми элементами,
// неявное приведение могло произойти без ошибки компиляции,
// но могло вызвать ошибку при доступе к элементам.
dynamic actualList = [1, 'hello'];
List<int> potentiallyUnsafeList = actualList; // Неявное приведение
// Попытка доступа к элементу могла привести к ошибке времени выполнения
// print(potentiallyUnsafeList[1] + 1); // Ошибка времени выполнения!
}
// После Dart 2.10
void processListSafe(List<int> list) {
dynamic actualList = [1, 'hello'];
// Здесь потребуется явное приведение
// List<int> unsafeList = actualList; // Ошибка компиляции в Dart 2.10+
// Явное приведение с проверкой
if (actualList is List<int>) {
List<int> safeList = actualList; // Приведение безопасно после проверки
print(safeList[0] + 1);
} else {
print("Список не является List<int>");
}
// Или явное приведение с оператором as.
// Важно: если actualList не является List<int>, это выбросит ошибку времени выполнения.
try {
List<int> anotherSafeList = actualList as List<int>;
print(anotherSafeList[0] + 1);
} on TypeError {
print("Ошибка типа при явном приведении");
}
}
Таким образом, отказ от неявного приведения типов в Dart 2.10 сделал язык более типо-безопасным и подготовил основу для Sound Null Safety.