此答案是对添加到原始问题的赏金的回应。赏金写道:
请解释与 Dart 中的类型提升有何String?
不同以及如何工作。String
细绳?与字符串
该类型String?
可以包含字符串或null
. 这里有些例子:
String? string1 = 'Hello world';
String? string2 = 'I ❤️ Dart';
String? string3 = '';
String? string4 = null;
另一方面,String 类型只能包含字符串(也就是说,一旦 null 安全是 Dart 的一部分)。它不能包含null
. 这里有些例子:
String string1 = 'Hello world';
String string2 = 'I ❤️ Dart';
String string3 = '';
如果您尝试执行以下操作:
String string4 = null;
你会得到编译时错误:
A value of type 'Null' can't be assigned to a variable of type 'String'.
类型String
不能null
超过int
like3
或bool
like 。true
这就是零安全的全部意义所在。如果您有一个类型为 的变量,则String
可以保证该变量永远不会是null
。
类型提升的工作原理
如果编译器可以在逻辑上确定可空类型(如String?
)永远不会是null
,则它将类型转换(或提升)为其不可为空的对应类型(如String
)。
这是一个正确的示例:
void printNameLength(String? name) {
if (name == null) {
return;
}
print(name.length);
}
虽然参数name
可以为空,但如果它确实是,null
那么函数会提前返回。当你到达的时候name.length
,编译器肯定知道这是name
不可能的null
。所以编译器将 name 提升为String?
to String
。该表达式name.length
永远不会导致崩溃。
这里有一个类似的例子:
String? name;
name = 'Bob';
print(name.length);
虽然name
在这里也可以为空,但字符串文字'Bob'
显然是非空的。这也导致name
被提升为不可为空的String
。
最初的问题是关于以下内容:
String? name = 'Bob';
print(name.length);
似乎这也应该将 name 提升为 non-nullable String
,但事实并非如此。正如@lrn(谷歌工程师)在评论中指出的那样,这是一个错误,当出现空安全性时,这也将像前面的示例一样工作。也就是说,name
将被提升为不可为空的String
.
进一步阅读