为什么 Dart 中允许不正确的类型分配?
Why are incorrect type assignments allowed in 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
在 this tutorial 我发现,它说:
But the snippet below generates an error because the compiler identifies b as an int that is wrongly being assigned a double value. This is type-checking in action, and one of the many ways that Dart improves on JavaScript.
int b=7898765;
b = 9.8; // ERROR Can't assign double to int
但是,无论是在使用 Dartium 还是在使用 <script src="packages/browser/dart.js"></script>
时,该代码都不会为我生成错误。
如果我这样做 var i = "abc" + 1.5
,它会抛出一个错误,那么为什么类型错误分配不做同样的事情呢?这是疏忽还是设计选择?如果是后者,原因是什么?
提前致谢。
此答案仅适用于 Dart 1.x
在 Dart 中,当 运行 处于生产模式(默认)时,类型注释将被忽略。如果您 运行 在检查模式下检查类型。如果您在实例上调用不存在的方法,仍会抛出异常。
var i = "abc" + 1.5
+
运算符(方法)显然会对参数进行类型检查并抛出异常,因为它不是非字符串值。
对于从 Dart 生成的 JS,您可以通过添加
配置 $dart2js
转换器以生成“检查模式”输出
transformers:
- $dart2js:
checked: true
到您的 pubspec.yaml
文件(有关更多 $dart2js
选项,请参阅 Configuring the Built-in dart2js Transformer for Pub)。
这仅在您使用 pub build
构建时生效。如果您直接使用 dart2js
生成 JS,请传递 -c
标志以创建检查模式输出。
对于服务器 VM 上的代码 运行 也传递 -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 deserialization pattern)
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'
我知道 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
在 this tutorial 我发现,它说:
But the snippet below generates an error because the compiler identifies b as an int that is wrongly being assigned a double value. This is type-checking in action, and one of the many ways that Dart improves on JavaScript.
int b=7898765;
b = 9.8; // ERROR Can't assign double to int
但是,无论是在使用 Dartium 还是在使用 <script src="packages/browser/dart.js"></script>
时,该代码都不会为我生成错误。
如果我这样做 var i = "abc" + 1.5
,它会抛出一个错误,那么为什么类型错误分配不做同样的事情呢?这是疏忽还是设计选择?如果是后者,原因是什么?
提前致谢。
此答案仅适用于 Dart 1.x
在 Dart 中,当 运行 处于生产模式(默认)时,类型注释将被忽略。如果您 运行 在检查模式下检查类型。如果您在实例上调用不存在的方法,仍会抛出异常。
var i = "abc" + 1.5
+
运算符(方法)显然会对参数进行类型检查并抛出异常,因为它不是非字符串值。
对于从 Dart 生成的 JS,您可以通过添加
配置$dart2js
转换器以生成“检查模式”输出
transformers:
- $dart2js:
checked: true
到您的 pubspec.yaml
文件(有关更多 $dart2js
选项,请参阅 Configuring the Built-in dart2js Transformer for Pub)。
这仅在您使用 pub build
构建时生效。如果您直接使用 dart2js
生成 JS,请传递 -c
标志以创建检查模式输出。
对于服务器 VM 上的代码 运行 也传递 -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 deserialization pattern)
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'