深色模式
Dart 空安全
空安全
空安全的意义
Dart 语言强制执行健全的空安全机制。空安全能够避免因意外访问被设置为 null
的变量而引发的错误。例如,若一个方法期望接收一个整数,但实际接收到 null
,应用程序就会产生运行时错误,这种错误即空引用错误,往往难以调试。
健全空安全的规则
在健全空安全机制下,所有变量都需要有值,这意味着 Dart 默认将所有变量视为非空类型。你只能为变量赋予其声明类型的值,例如 int i = 42
,默认的变量类型永远不能被赋值为 null
。若要指定变量类型可以为 null
,需在类型注解后添加 ?
,如 int? i
,这种特定类型既可以包含 null
,也可以包含定义类型的值。
健全空安全能将潜在的运行时错误转化为编辑时的分析错误。借助空安全,Dart 分析器和编译器会在以下两种情况下标记非空变量:
- 未使用非空值进行初始化。
- 被赋值为
null
。
这些检查机制让你在部署应用之前就能修复这些错误。
通过示例介绍空安全
在空安全机制下,以下代码中的变量都不能为 null
:
dart
// 在空安全机制下,这些变量都不能为 null。
var i = 42; // 推断为 int 类型。
String name = getFileName();
final b = Foo();
若要表明变量可能为 null
,只需在其类型声明后添加 ?
:
dart
int? aNullableInt = null;
你可以尝试 Dart 速查表中一些以空安全为导向的交互式示例。若想深入了解空安全,可查阅《理解空安全》。
空安全原则
Dart 通过以下两个核心设计原则来支持空安全:
- 默认非空:除非你明确告知 Dart 某个变量可以为
null
,否则它会被视为非空类型。该默认设置是在研究发现 API 中绝大多数情况下都选择非空类型后确定的。 - 完全健全:Dart 的空安全是健全的,这为编译器优化提供了可能。如果类型系统判定某个对象不为
null
,那么它就绝对不会为null
。当你将整个项目及其依赖都迁移到空安全机制后,就能充分享受到健全性带来的好处,不仅能减少错误,还能使二进制文件更小、执行速度更快。
Dart 3 与空安全
Dart 3 内置了健全的空安全机制,它会阻止不具备空安全的代码运行。若要了解如何迁移到 Dart 3,可查阅《Dart 3 迁移指南》。不支持空安全的包在解决依赖关系时会引发问题:
plaintext
$ dart pub get
Because pkg1 doesn't support null safety, version solving failed.
The lower bound of "sdk: '>=2.9.0 <3.0.0'" must be 2.12.0 or higher to enable null safety.
与 Dart 3 不兼容的库会导致分析或编译错误:
plaintext
$ dart analyze .
Analyzing .... 0.6s
error • lib/pkg1.dart:1:1 • The language version must be >=2.12.0.
Try removing the language version override and migrating the code.
• illegal_language_version_override
$ dart run bin/my_app.dart
../pkg1/lib/pkg1.dart:1:1: Error: Library doesn't support null safety.
// @dart=2.9
^^^^^^^^^^^^
要解决这些问题,你可以:
- 检查从
pub.dev
安装的所有包是否有支持空安全的版本。 - 将所有源代码迁移到使用健全的空安全机制。
Dart 3 可在 Dart 和 Flutter 的稳定通道中获取。若想了解更多信息,可查看下载页面的详细内容。若要测试代码与 Dart 3 的兼容性,可使用 Dart 3 或更高版本:
plaintext
$ dart --version # 确保显示 3.0.0 - 417.1.beta 或更高版本
$ dart pub get / flutter pub get # 此步骤应能顺利解决依赖问题
$ dart analyze / flutter analyze # 此步骤应能通过且无错误
若 pub get
步骤失败,需检查依赖项的状态;若 analyze
步骤失败,需更新代码以解决分析器列出的问题。
Dart 2.x 与空安全
从 Dart 2.12 到 2.19 版本,你需要手动启用空安全,而在早于 Dart 2.12 的 SDK 版本中无法使用空安全。若要启用健全的空安全,需将 SDK 约束的下限设置为 2.12 或更高的语言版本。例如,你的 pubspec.yaml
文件可能有如下约束:
yaml
environment:
sdk: '>=2.12.0 <3.0.0'
迁移现有代码
警告:Dart 3 移除了 dart migrate
工具。若你需要该工具帮助迁移代码,可使用 2.19 SDK 运行该工具,然后再升级到 Dart 3。当然,你也可以不使用该工具进行迁移,但这需要手动编辑代码。
不支持空安全的 Dart 代码可以迁移到使用空安全。我们建议使用 Dart SDK 2.12 到 2.19 版本中包含的 dart migrate
工具:
plaintext
$ cd my_app
$ dart migrate