设计原则
在开始针对 null safety
的详细设计之前,Dart 团队定义了以下三个核心原则:
-
默认情况下不可为空,除非开发者明确告知 Dart 变量可以为
null
,否则它将认为该变量不可为空。选择这个作为默认选项,因为我们发现 non-nullable 是迄今为止 API 中最常见的选择。 -
逐步采用,因为还有有很多 Dart 代码需要修改,必须把它们逐步迁移到
null safety
。在同一项目中应该可以包含null safety
代码和non-null-safe
代码,另外我们还将提供工具来帮助开发者进行迁移。 -
完全可靠,如上所述 Dart 的
null safety
是可靠的,将整个项目和依赖项迁移到null
安全之后,将获得稳健性带来的全部好处。
声明变量的 null safety
核心语法很简单,提供一些不同方式来声明 non-nullable 变量,并且默认值是不可为空的,因此这些声明看起来和之前好像一样,但是它们的含义发生了变化。
// In null-safe Dart, none of these can ever be null.
var i = 42;
final b = Foo();
String m = ‘’;
Dart 将确保绝不会分配给上述变量任何 null 值。如果尝试执行 i = null
,则会出现静态分析错误和红色的弯曲提示,并且无法继续编译。
如果开发者希望变量可为空,如下所示则可以使用?
:
// These are all nullable variables.
int? j = 1; // Can be null later.
final Foo? c = getFoo(); // Maybe the function returns null.
String? n; // Is null at first. Can be null at any later time, too.
另外也可以将 ?
在运用到其他需要的地方:
// In function parameters.
void boogie(int? count) {
// It’s possible that count is null.
}
// In function return values.
Foo? getFoo() {
// Can return null instead of Foo.
}
// Also: generics, typedefs, type checks, etc.
// And any combination of the above.
但是,我们是希望你可以不需要使用到 ?
,因为绝大多数类型都是可以不必为空的。
使 null safety 更简易使用
Dart 开发小组正在努力使 null safety
尽可能方便使用,例如下面的代码,该代码 if
用于检查空值:
void honk(int? loudness) {
if (loudness == null) {
// No loudness specified, notify the developer
// with maximum loudness.
_playSound(‘error.wav’, volume: 11);
return;
}
// Loudness is non-null, let’s just clamp it to acceptable levels.
_playSound(‘honk.wav’, volume: loudness.clamp(0, 11));
}
这里可以看到 Dart 已经足够智能,以至于在我们传递该 if
语句时,loudness
变量其实已经保证不会为 null
。 因此 Dart 让我们调用该 clamp()
方法而无需进行判空。这种便利是通过 Flow analysis
的方法来实现:Dart分析器像执行代码一样浏览你的代码,自动找出有关代码的其他信息。
这是还有另一个示例,它显示了 Dart 可以确保变量为非 null
的情况,因为我们总是为其分配一个非 null
值:
int sign(int x) {
// The result is non-nullable.
int result;
if (x >= 0) {
result = 1;
} else {
result = -1;
}
// By this point, Dart knows the result cannot be null.
return result;
}
如果开发者删除了上述部分逻辑(例如,通过删除 result = -1;
),则 Dart 无法保证 result
为非 null
,所以开发者将得到一个静态错误,并且代码会无法编译。
Flow analysis
仅在函数内部起作用,如果你有全局变量或类字段,则 Dart 无法保证何时为其分配什么值,Dart 也无法为整个应用程序流程建模。因此,当你在第一次读取变量之前,就知道变量将为非空时,可以使用 late
关键字声明,但是不能立即对其进行初始化。
class Goo {
late Viscosity v;
Goo(Material m) {
v = m.computeViscosity();
}
}
请注意 v
它是非空的,尽管它开始时未初始化,但是 Dart 相信开发者不会在没有 v
赋值之前尝试读取它,所以代码可以正确编译。
null safety 是向后兼容
Dart 团队已经进行了一年多的工作,以确保 null safety
的技术预览可靠。自从我们引入 Dart 2 以来,这是 Dart 语言最大的功能添加,但这并不是一个重大变化。现有代码可以使用null safety
代码,反之亦然。即使在提供 null safety
之后,它也将是一项可选功能,开发者可以在准备就绪时采用它,你现有的代码将继续运行而无需更改。
我们最近迁移了 Dart 的核心库,以完全使用 null safety
。作为 null safety
是向后兼容的一个示例,我们替换了现有的核心库,而在 Dart 和 Flutter 测试环境中运行的现有测试和测试应用程序没有任何 break。
我们甚至将许多新的核心库直接投放给 Google 的内部客户,这些客户直接运行进入了他们的生产代码库。我们计划迁移所有软件包和应用程序,以在功能启动时使用 null safety
,希望你也能这样做。
null safety 路线图
我们计划分三步逐步推出无效安全性:
- 技术预览 :可在 Dart 的 dev channel 中找到,因为此刻仍可能发生未知变化,因此暂时不要在生产代码中使用
null safety
。 - Beta版 :在 Dart 的 beta channel 中将提供
null safety
,该功能将非常接近预期的最终版本。如果拥有 pub.dev 软件包或插件,则可以开始迁移,但现在还不应该将其发布为稳定版本。 - 稳定发布 :每个开发者都可以正常使用
null safety
,因此建议你将迁移的软件包和插件发布为稳定版本。
如果一切顺利,我们计划在年底之前发布 null safety
到 stable,从现在开始我们将添加工具来帮助您使用 null safety
,包括:
- 迁移工具可支持你自动执行迁移升级,将现有软件包和应用程序迁移到
null safety
; - 增加 pub.dev 上的标签,因此你
《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
【docs.qq.com/doc/DSkNLaERkbnFoS0ZF】 完整内容开源分享
可以判断软件包是否支持 null safety
;
- pub outdated 命令的扩展,支持支持查找
null safety
依赖关系的最新版本;
现在就试试
现在尝试 null safety
最快的方法是通过 nullsafety.dartpad.dev,这是启用了空安全性的 DartPad 版本,打开 “Learn with Snippets” 下拉列表找到一系列学习例子,这些学习例子介绍了新的语法和 null safety
的基础知识。
另外我们也有文档和产品更多的发布计划:
- Null safety guide
下拉列表找到一系列学习例子,这些学习例子介绍了新的语法和null safety
的基础知识。
[外链图片转存中…(img-4BE6CRol-1640001959935)]
另外我们也有文档和产品更多的发布计划: - Null safety guide