Dart null safety - 以 null 安全的方式从映射中检索值

Seb*_*nJL 16 dart dart-null-safety

我有类似于此示例代码的代码(不要介意它没有意义):

void foo(Map<int, String> myMap) {
  String s = myMap[1];
}
Run Code Online (Sandbox Code Playgroud)

dart 分析器向我发出有关该行的警告,String s = myMap[1];并显示以下警告:

“字符串?”类型的值 不能分配给“String”类型的变量。尝试更改变量的类型,或将右侧类型转换为“String”。

我看到这种情况正在发生,因为从地图中检索值可能会导致null. 为什么下面的代码片段给了我同样的警告?

void foo(Map<int, String> myMap) {
  if (myMap.containsKey(1)) {
    String s = myMap[1];
  }
}
Run Code Online (Sandbox Code Playgroud)

Cop*_*oad 15

问题:

\n

来自文档

\n
\n

如果键不存在,则 Map 类上的索引 [] 运算符将返回 null。这意味着该运算符的返回类型必须可为空。

\n
\n

看看下面的代码。b由于中缺少键Map,因此如果已通过静态分析,map[\'b\']则返回null并将其值分配给int将会导致错误。runtime

\n
Map<String, int> map = {\'a\': 1};\nint i = map[\'b\']; // Error: You can\'t assign null to a non-nullable field.\n
Run Code Online (Sandbox Code Playgroud)\n
\n

解决方案:

\n\n

  • @AlexJean Docs 不明确**推荐**`??`,但使用它比使用 bang 运算符安全得多。 (2认同)

lrn*_*lrn 3

警告完全基于操作的类型。aoperator []返回Map<K,V>a V?,所以可能是null。类型系统不知道键是否在映射中,甚至不知道映射什么。

您调用另一个暗示返回值不会null改变类型的方法,并且编译器不会得到该暗示。