dart - 为什么将动态分配给不可为 null 的对象不是具有健全的 null 安全性的错误

标签 dart nullable static-analysis

在打开声音空安全的 dart 中,完全有可能做到

dynamic myVar; // myVar assumes default value of null
String someString = myVar; // No warning by IDE.

正如预期的那样,自 myVar 以来,上述结果会导致运行时错误为空且 someString不可为空。

这是 linter/IDE 的问题吗?

我确实发现我可以启用迂腐的 linting,当我尝试隐式地将 dynamic 转换为另一种类型时,它会导致 IDE 显示警告。启用它会有所帮助,但我认为问题在于动态可以为空,而不必明确定义为可为空。

总之我们没有

dynamic? myNullableVar;

我的问题是:这是一个错误吗?

当你做类似的事情时,这个“问题”最常困扰你

Map<String, dynamic> myData = jsonDecode(receivedResponseBody);
var name = myData['name'];

在上面的示例中,我希望 IDE 显示一条警告,表明我正在尝试将可能为 null 的值分配给不可为 null 的变量。 IDE 应要求用户添加空检查。

如果这不是错误(在 IDE 或 linter 中),那为什么不呢?

长话短说:从 dynamic 到另一种类型的隐式转换掩盖了空赋值的问题,我希望 IDE 会提供警告。


编辑:在下面@jamesdlin 的注释之后 具体来说,我同意以下分配的左侧允许空值的地方。

dynamic someVar;
String? myString = someVar;

旁注,我希望新的 dart typeDef 功能允许我在 Python 中构建类似于 Union 类型提示的东西。那会让我得到类似的东西

typeDev JsonValueType = { int, String, float, bool };

然后 jsonDecode 的结果将是

Map<String, JsonValueType?>

它明确包含 Null,因此 IDE 会警告用户添加空检查。

我的观点:只要您可以将赋值运算符右侧的任何可空类型赋值给左侧的不可空类型,您就没有真正可靠的空安全。

最佳答案

这不是错误。

你可以这样做:

dynamic x = "not an int";
int y = x;

并且不会收到任何编译器警告。这就是 dynamic 的工作原理,它关闭编译器(“静态”)类型检查并转而依赖运行时(“动态”)检查。这就是名字的由来。

没有理由允许 dynamic? 因为 dynamic 已经允许 null 值(和任何其他值)。 dynamic 类型本质上可以为空,向其添加? 没有任何区别,就像Null? 一样没有意义。

Dart 类型系统是静态的空声音(大多数情况下,适用泛型的常见警告),但动态 是一种根据请求关闭 的类型系统。不要使用 dynamic 除非你想要那种效果。

关于dart - 为什么将动态分配给不可为 null 的对象不是具有健全的 null 安全性的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67647232/

相关文章:

flutter - 如何在 Flutter 中导入 intl 库?

dart - 构造函数:将预处理的参数存储在传递给最终字段的辅助变量中

c - 静态代码分析器工具中的函数调用列表

c# - 使用 LINQ 将 DateTime?[] 中的 null 替换为 DateTime.MaxValue

llvm - 如何从 LLVM 的 MemoryDe​​pendenceAnalysis 传递中获得更好的结果?

c - 如何使用 Frama-C 将变量类型保存到文件

flutter - 第一个功能太慢,该怎么办?

flutter 禁用整个屏幕上的触摸

c# - 比较 Nullable DateTime 变量的默认值

c# - 将 struct 与 null 进行比较时出现错误的编译器警告