Ответ
dynamic — это специальный тип в Dart, который отключает статическую проверку типов для переменной. Компилятор разрешает переменной типа dynamic содержать значение любого типа, а проверка корректности операций откладывается до времени выполнения (runtime).
Ключевые отличия:
-
dynamicvsObject: Оба могут хранить любое значение. Но сObjectкомпилятор запрещает выполнять произвольные операции (например, вызывать методы) без явного приведения типа (as). Сdynamicкомпилятор разрешает любые операции, а проверка произойдет в рантайме.Object obj = 'строка'; // print(obj.length); // Ошибка компиляции: The getter 'length' isn't defined for 'Object'. print((obj as String).length); // Нужно явное приведение. dynamic dyn = 'строка'; print(dyn.length); // Компиляция проходит, в runtime вызовется .length у String. dyn = 42; print(dyn.length); // Runtime ошибка: NoSuchMethodError (у int нет .length). -
dynamicvsvar:var— это синтаксический сахар, тип переменной выводится компилятором один раз при инициализации и далее не меняется.dynamic— это явный тип, который разрешает менять тип значения.var inferred = 'hello'; // Тип выведен как String. // inferred = 42; // Ошибка компиляции: A value of type 'int' can't be assigned. dynamic explicit = 'hello'; // Тип dynamic. explicit = 42; // OK.
Когда использование dynamic оправдано:
- Работа с JSON или внешними API со слабой типизацией: При десериализации данных неизвестной структуры, пока они не будут приведены к конкретным моделям.
Map<String, dynamic> json = jsonDecode(response.body); String name = json['user']['name']; // Доступ к полям возможен, тип проверяется в runtime. - Вызов методов через рефлексию (dart:mirrors) или при работе с
dart:jsдля JavaScript-интеропа. - В прототипах или скриптах, где скорость написания кода важнее его безопасности.
Рекомендация: Следует минимизировать использование dynamic в production-коде Flutter-приложений. Это ослабляет помощь инструментов (автодополнение, статический анализ) и увеличивает риск runtime-ошибок (NoSuchMethodError). Всегда предпочитайте строгую типизацию. Если структура данных известна, используйте модели с кодогенерацией (json_serializable, freezed). Если тип может быть одним из нескольких — используйте union-типы или классы-обертки.