Dart 语言已支持健全的空安全机制!

The Dart language now supports sound null safety!

当您选择使用空安全时,代码中的类型将默认是非空的,意味着 除非您声明它们可空,它们的值都不能为空。有了空安全,原本处于您的 运行时 的空值引用错误将变为 编辑时 的分析错误。

When you opt into null safety, types in your code are non-nullable by default, meaning that variables can’t contain null unless you say they can. With null safety, your runtime null-dereference errors turn into edit-time analysis errors.


With null safety, all of the variables in the following code are non-nullable:

// In null-safe Dart, none of these can ever be null.
var i = 42; // Inferred to be an int.
String name = getFileName();
final b = Foo();

若您想让变量可以为 null,只需要在类型声明后加上 ?

To indicate that a variable might have the value null, just add ? to its type declaration:

int? aNullableInt = null;

您可以 在您的开发项目里尝试空安全迁移您项目中的代码 至空安全、或者通过 支持空安全的 DartPad 进行练习,如下面的截图所示。

You can use null safety in your normal development environment, migrate existing code to use null safety, enable null safety in DartPad, or learn about null safety using DartPad with Null Safety (shown in the following screenshot).

Screenshot of DartPad in null-safe mode

若您想通过示例快速了解空安全,可以查看 空安全功能之旅。更深入的探讨,可以阅读 深入理解空安全

For an example-driven summary of null safety language features, see the null safety feature tour. For a more in-depth discussion, see Understanding null safety.


Null safety principles

Dart 的空安全支持基于以下三条核心原则:

Dart null safety support is based on the following three core design principles:

  • 默认不可空。除非您将变量显式声明为可空,否则它一定是非空的类型。我们在研究后发现,非空是目前的 API 中最常见的选择,所以选择了非空作为默认值。

    Non-nullable by default. Unless you explicitly tell Dart that a variable can be null, it’s considered non-nullable. This default was chosen after research found that non-null was by far the most common choice in APIs.

  • 渐进迁移。您可以自由地选择何时进行迁移,多少代码会进行迁移。您可以使用混合模式的空安全,在一个项目中同时使用空安全和非空安全的代码。我们也提供了帮助您进行迁移的工具。

    Incrementally adoptable. You choose what to migrate to null safety, and when. You can migrate incrementally, mixing null-safe and non-null-safe code in the same project. We provide tools to help you with the migration.

  • 完全可靠。Dart 的空安全是非常可靠的,意味着编译期间包含了很多优化。如果类型系统推断出某个变量不为空,那么它 永远 不为空。当您将整个项目和其依赖完全迁移至空安全后,您会享有健全性带来的所有优势——更少的 BUG、更小的二进制文件以及更快的执行速度。

    Fully sound. Dart’s null safety is sound, which enables compiler optimizations. If the type system determines that something isn’t null, then that thing can never be null. Once you migrate your whole project and its dependencies to null safety, you reap the full benefits of soundness —- not only fewer bugs, but smaller binaries and faster execution.


Enabling null safety

健全的空安全已在 Dart 2.12 和 Flutter 2 中可用。

Sound null safety is available in Dart 2.12 and Flutter 2.

迁移已有 package 或应用

Migrating an existing package or app

若您需要代码迁移的指导,请查看 迁移至空安全

For instructions on how to migrate your code to null safety, see the migration guide.

创建空安全版本的 package 或应用

Creating a null-safe package or app

使用 dart create 命令或 IDE 创建的模板尚未迁移至空安全。在创建后您还需要对它们进行迁移。举个例子:

The templates used by the dart create command and IDEs aren’t null safe yet, so you need to migrate the code they create. For example:

$ dart create -t console-full my_cli
$ cd my_cli
$ dart migrate --apply-changes

幕后工作:SDK 限制

Behind the scenes: SDK constraints

SDK 版本约束 设定为一个支持空安全的 SDK 版本。例如,您的 pubspec.yaml 可以设置为如下的限制:

To make Dart treat your code as null safe, the SDK constraints must require a language version that has null safety support. For example, your pubspec.yaml file might have the following constraints:

  sdk: ">=2.12.0 <3.0.0"


Known issues

Dart 的生态 迁移到空安全 仍然需要一些额外的工作。

Some parts of the Dart ecosystem still need additional work to migrate to null safety.

Dart 团队已知晓以下问题:

The Dart team is currently aware of the following issues:

  • pub.dev 上属于 Dart 团队的一些 package 尚有部分未进行迁移。您可以查看 pub.dev 上 Dart 团队已迁移的 package

    Migration of the pub.dev packages owned by the Dart team is nearly complete, but a few are still missing. See pub.dev for null-safe packages from the Dart team.

  • 包含单元测试的 package,均通过开发依赖引用了 test package。部分 package 由于扩展了 test package 的框架,可能有直接引用的关联。在您发布 package 时可能会遇到 test package 尚未迁移的警告。只要您未让分析器忽略 import_of_legacy_library_into_null_safe 或者 export_legacy_symbol 的警告,您实际上可以忽略这个迁移警告。

    Packages that have unit tests typically have a dev dependency on the test package. A few packages extend the framework in package:test, and might have a direct dependency on it. When publishing these packages you might get pub warnings about the test package not being fully migrated. As long as your package doesn’t ignore any of the import_of_legacy_library_into_null_safe or export_legacy_symbol analyzer warnings, then you can ignore this warning and safely publish your package.


Where to learn more

For more information about null safety, see the following resources: