dart - 分配非空值文字时的空安全类型提升

标签 dart type-promotion dart-null-safety

nullsafety.dartpad.dev如果我编写以下代码:

void main() {
  String? name = 'Bob';
  print(name.length);
}
我收到以下编译时错误:

An expression whose value can be 'null' must be null-checked before it can be dereferenced


以及以下运行时错误:

Property 'length' cannot be accessed on 'String?' because it is potentially null.


Type promotion on null checks文档说:

The language is also smarter about what kinds of expressions cause promotion. An explicit == null or != null of course works. But explicit casts using as, or assignments, or the postfix ! operator we’ll get to soon also cause promotion. The general goal is that if the code is dynamically correct and it’s reasonable to figure that out statically, the analysis should be clever enough to do so.



没有办法name在上面的代码中可能为空。该文档还说分配应该导致类型提升。我误解了类型提升还是 DartPad 中的错误?
澄清
由于几个答案为错误消息提供了解决方法,我应该澄清我不是在尝试解决上面的编码问题。相反,我是说我认为代码应该按原样工作。但事实并非如此。为什么不?

最佳答案

此答案是对添加到原始问题的赏金的回应。赏金内容如下:

Please explain how String? is different from String and how type promotion works in Dart.


字符串? VS 字符串
型号String?可以包含字符串或 null .这里有些例子:
String? string1 = 'Hello world';
String? string2 = 'I ❤️ Dart';
String? string3 = '';
String? string4 = null;
另一方面,String 类型只能包含字符串(一旦空安全是 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喜欢 3bool喜欢 true .这就是空安全的全部意义所在。如果您有一个类型为 String 的变量,您可以保证变量永远不会是 null .
类型提升的工作原理
如果编译器可以从逻辑上确定可空类型(如 String? )永远不会是 null ,然后它将类型转换(或提升)为其不可为空的对应物(如 String )。
这是一个正确的例子:
void printNameLength(String? name) {
  if (name == null) {
    return;
  }
  print(name.length);
}
虽然参数name可以为空,如果它实际上是 null然后函数提前返回。当您到达 name.length 时,编译器肯定知道 name不能是 null .所以编译器从 String? 提升 name至 String .表达式 name.length永远不会导致崩溃。
一个类似的例子在这里:
String? name;
name = 'Bob';
print(name.length);
虽然 name这里也可以为空,字符串文字 'Bob'显然是非空的。这也会导致 name被提升为不可为空的 String .
最初的问题是关于以下内容:
String? name = 'Bob';
print(name.length);
似乎这也应该将 name 提升为不可为空的 String ,但它没有。正如@lrn(Google 工程师)在 comments 中指出的那样,但是,这是一个错误,当空安全出现时,这也将像前面的示例一样工作。即,name将被提升为不可为空的 String .
进一步阅读
  • Sound null safety
  • Type promotion on null checks
  • 关于dart - 分配非空值文字时的空安全类型提升,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63531488/

    相关文章:

    flutter - 关闭并重新打开礼物后,使礼物从头开始

    angular - 无法将广告放入我的 Angular Dart 应用程序

    c++ - 带有 size_t 的奇怪循环

    c - unsigned char 总是提升为 int 吗?

    flutter - 运算符 '*' 不能无条件调用,因为接收者可以是 'null' 。尝试向目标 ('!' 添加空检查)

    google-maps - 如何在Flutter上使用placeId获取Google地方信息?

    post - 为什么 HttpRequest 发送 OPTIONS 动词而不是 POST?

    c++ - 嵌套 vector 不遵循提升规则。解决方案有一个错误。

    Flutter - Mockito - 在测试中使用 async 会产生错误,但使用 async* 可以正常工作吗?

    kotlin - Dart "sound null-safety"与 Kotlin 空安全有何不同?