Sur*_*gch 7 dart type-promotion dart-null-safety
在nullsafety.dartpad.dev 中,如果我编写以下代码:
void main() {
String? name = 'Bob';
print(name.length);
}
Run Code Online (Sandbox Code Playgroud)
我收到以下编译时错误:
值可以为“空”的表达式必须先进行空检查,然后才能取消引用
以及以下运行时错误:
无法在“字符串?”上访问属性“长度” 因为它可能为空。
该语言在什么样的表达方式会导致提升方面也更加聪明。一个明确的
== null
或!= null
当然的作品。但是使用as
、赋值或后缀!
运算符的显式转换也会导致提升。总体目标是,如果代码是动态正确的,并且可以合理地静态计算出来,那么分析应该足够聪明来做到这一点。
有没有可行的方法name
可能是空在上面的代码。该文档还说分配应该导致类型提升。我误解了类型提升还是 DartPad 中的错误?
由于一些答案为错误消息提供了解决方法,我应该澄清一下,我不是在尝试解决上面的编码问题。相反,我是说我认为代码应该按原样工作。但事实并非如此。为什么不?
此答案是对添加到原始问题中的赏金的回应。赏金内容如下:
\n\n\n请解释
\nString?
与 Dart 中的 type\npromotion 有何不同String
以及其工作原理。
该类型String?
可以包含字符串或null
. 这里有些例子:
String? string1 = \'Hello world\';\nString? string2 = \'I \xe2\x9d\xa4\xef\xb8\x8f Dart\';\nString? string3 = \'\';\nString? string4 = null;\n
Run Code Online (Sandbox Code Playgroud)\n另一方面,String 类型只能包含字符串(一旦 null 安全性成为 Dart 的一部分)。它不能包含null
. 这里有些例子:
String string1 = \'Hello world\';\nString string2 = \'I \xe2\x9d\xa4\xef\xb8\x8f Dart\';\nString string3 = \'\';\n
Run Code Online (Sandbox Code Playgroud)\n如果您尝试执行以下操作:
\nString string4 = null;\n
Run Code Online (Sandbox Code Playgroud)\n你会得到编译时错误:
\nA value of type \'Null\' can\'t be assigned to a variable of type \'String\'.\n
Run Code Online (Sandbox Code Playgroud)\n类型String
不能null
超过int
like3
或 a bool
like true
。这就是零安全的意义所在。如果您有一个类型为 的变量String
,则可以保证该变量永远不会是null
。
如果编译器可以从逻辑上确定可为 null 的类型(例如String?
)永远不会是null
,那么它会将该类型转换(或提升)为其不可为 null 的对应类型(例如String
)。
下面是一个例子,说明这一点是正确的:
\nvoid printNameLength(String? name) {\n if (name == null) {\n return;\n }\n print(name.length);\n}\n
Run Code Online (Sandbox Code Playgroud)\n尽管该参数name
可以为空,但如果它实际上可以为空,null
则该函数会提前返回。当您到达时name.length
,编译器肯定知道这是name
不可能的null
。因此编译器将 name 从 提升String?
为String
。该表达式name.length
永远不会导致崩溃。
类似的例子在这里:
\nString? string1 = \'Hello world\';\nString? string2 = \'I \xe2\x9d\xa4\xef\xb8\x8f Dart\';\nString? string3 = \'\';\nString? string4 = null;\n
Run Code Online (Sandbox Code Playgroud)\n虽然name
这里也可以为空,但字符串文字\'Bob\'
显然是非空的。这也会导致name
提升为非 nullable String
。
最初的问题是关于以下内容:
\nString string1 = \'Hello world\';\nString string2 = \'I \xe2\x9d\xa4\xef\xb8\x8f Dart\';\nString string3 = \'\';\n
Run Code Online (Sandbox Code Playgroud)\n似乎这也应该将 name 提升为 non-nullable String
,但事实并非如此。不过,正如 @lrn(Google 工程师)在评论中指出的那样,这是一个错误,当 null safety 出现时,这也将像前面的示例一样工作。也就是说,name
将提升为不可为空的String
。
归档时间: |
|
查看次数: |
839 次 |
最近记录: |