Почему в 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'