Dart tour: 19、Sound null safety
健全的 空安全 特性已在
Dart 2.12和Flutter 2中可用。
空安全#
当空安全机制启用时,代码中的类型将默认是非空的。这意味着除非声明为可空,否则它们的值都不能为空。
若您想让变量可以为空,只需要在类型声明后加上 ?。
空安全支持基于以下三条核心原则:
非空是目前的 API 中最常见的选择,所以选择了非空作为默认值。
默认不可空。除非将变量显式声明为可空,否则它一定是非空的类型。渐进迁移。可以自由地选择何时进行迁移,多少代码会进行迁移。您可以使用混合模式的空安全,在一个项目中同时使用空安全和非空安全的代码。完全可靠。空安全是非常可靠的,这意味着编译期间包含了很多优化。如果类型系统推断出某个变量不为空,那么它永远不为空。
如果旧应用需要迁移至空安全的话,可以参考这篇文档。
检查是否支持空安全#
Dart#
在命令行中运行命令,查看打印的版本号是否大于等于 2.12。
Flutter#
在应用的 pubspec.yaml 将 SDK 版本约束设定为一个支持空安全的 SDK 版本。
非空和可空类型#
在空安全机制不存在的时候,Null 类型被看作是所有类型的子类。当变量为 null 时,调用方法可能会导致 NoSuchMethodError。此时的 Null 类型是所有类型的子类。

空安全通过修改了类型的层级结构,从根源上解决了这个问题。 Null 类型仍然存在,但它不再是所有类型的子类。现在的类型层级看起来是这样的。

如果表达式可能返回空值,在调用的需要需要使用 ?. 来访问对象的成员。只有访问同时在原有类型及 Null 类下同时定义的方法和属性时,可以直接使用. 来访问。如: toString()、== 和 hashCode。
禁用空安全#
想要测试或运行混合版本的代码,需要禁用空安全。有两种方式可以进行操作。
- 在
dart和flutter命令里,加入--no-sound-null-safety标记禁用。
- 或者,设定程序入口的语言版本 —— 包含
main()函数的文件 —— 设定为2.9