Почему в Dart допустимы неправильные назначения типов?

Я знаю, что типы являются в значительной степени необязательными для Dart, но если я решу указать тип переменной, я ожидаю, что присваивание будет int i = "abc" бросить ошибку во время выполнения. Однако ни то, ни другое не выдают ошибку, они просто игнорируют приведение типа.

  String str     = "test";
  int integer    = 5;
  double decimal = 1.5;
  List list      = [1,2,3];

  String s = decimal;   print(s);  // 1.5
  int i    = str;       print(i);  // test
  double d = list;      print(d);  // [1, 2, 3]
  List l   = integer;   print(l);  // 5

В этом уроке, которое я нашел, написано:

Но фрагмент ниже генерирует ошибку, потому что компилятор идентифицирует b как int, которому ошибочно присваивается двойное значение. Это проверка типов в действии, и один из многих способов, которые Dart улучшает в JavaScript.

int b = 7898765;

б = 9,8; // ОШИБКА Невозможно присвоить double для int

Тем не менее, этот код не генерирует ошибку для меня ни при использовании Dartium, ни при использовании <script src="packages/browser/dart.js"></script>,

Если я сделаю var i = "abc" + 1.5, он выдает ошибку, так почему же не присвоение типа делает то же самое? Это упущение или выбор дизайна? Если последнее, в чем причина?

Заранее спасибо.

1 ответ

Решение

В типе Dart аннотации просто игнорируются при запуске в производственном режиме (по умолчанию). Если вы работаете в проверенном режиме, типы проверяются. Если вы вызываете несуществующий метод в экземпляре, исключение все еще генерируется.

var i = "abc" + 1.5

+ Оператор (метод), очевидно, выполняет проверку типа аргумента и выдает его, потому что он не имеет строковых значений.

Для JS, сгенерированного из Dart, вы можете настроить $dart2js трансформатор для производства "проверенного режима" путем добавления

transformers:
- $dart2js:
    checked: true

на ваш pubspec.yaml файл (для более $dart2js параметры см. в разделе " Настройка встроенного преобразователя dart2js для паба"). Это вступает в силу только если вы строите с использованием pub build, Если вы используете dart2js непосредственно генерировать JS передать -c флаг, чтобы создать проверенный режим вывода.

Для запуска кода на сервере ВМ также передайте -c флаг как

dart -c your_script.dart

В своем вопросе вы не предоставили никакой информации о том, как вы запускаете свои скрипты Dart или как вы генерируете JS.

В этом простом DartPad редактор показывает ошибки статического анализа, что является еще одним примером использования для добавления аннотаций типов.

Dart 2.6 отвергает этот код.

A value of type 'double' can't be assigned to a variable of type 'String'

https://dartpad.dev/10ebe4bb74a11fe6e68efb351af40d1a

Я также тестировал Map<String, dynamic>(чтобы лучше понять шаблон десериализации JSON)

void main() {
  Map<String, dynamic> map = {
    'str': 'test',
    'integer': 5,
    'decimal': 1.5,
    'list': [1,2,3]
  };

  String s = map['decimal'];   print(s);  // JSDouble not String
  int i    = map['str'];       print(i);  // JSString not int
  double d = map['list'];      print(d);  // JSArray not double
  List l   = map['integer'];   print(l);  // JSInt not List
}

https://dartpad.dev/7bc355b3b7779d2b37e1aae2b6def050

и это также не удается во время выполнения, давая такие ошибки, как

TypeError: 1.5: type 'JSDouble' is not a subtype of type 'String'
Другие вопросы по тегам