Dart 2.12, Flutter 2 特性
Dart SDK 约束:
environment: |
介绍
在对空指针调用方法的时候,Dart 会抛出 NoSuchMethodError
的异常。
// Without null safety: |
因为 null 本身在 Dart 中也是个实例,是 Null 类的实例, 而 Null 类中并无此 length getter 方法所以抛异常
class Null { |
作用
- 能够让在你在开发阶段就可以捕获到由 null 而引发的 app 崩溃错误。
- 让程序更快更小,因为不需要对 non-nullable 变量进行判断是否为 null 了。
特性
- 默认变量的声明值都不能为 null, 即: non-nullable。
- 在变量的数据类型声明后加 ? 表示该变量可以有值也可以为 null, 即 nullable。
int? aNullableInt = null;
核心设计原则
- 默认是 non-nullable: 如果没有指定变量为 nullable,默认即为 non-nullable。
- 逐步迁移: 在工程中可以同时存在空安全和非空安全混编的代码,并提供工具逐步迁移。
- 完全符合健壮性: 只要类型系统确定该变量是 non-nullable,即该变量永远都不会为 null, 并开启了编译器优化,拥有更小的二进制以及更快的运行速度。
操作符
null-safety相关操作符 ! (assertion operator)、?、late
, 处理 nullable 的操作符 if、??、?.
late 关键字用于当无法对 non-nullable 立即赋值的时候,可以用该关键字延迟赋值, 注意 late 关键字和 fianl 是可以共存的。以下三点
- 不需要立即赋值。
- 可以稍后赋值
- 在访问之前确保赋值了。(没赋值即访问抛异常
LateInitializationError
)
late 除了可以延迟赋值外,还可以使成员方法懒加载,这对于读取大量耗时资源的时候十分有效,因为这些资源有可能用户不会用到,但是如果一开始就把这些资源就读取进来是没必要的,想做到需要读取的时候再进行读取。
?. 操作符号在 null-safety 有短路的功能,例如 person?.dog.age 如果 person 为 null, 那么整条表达式就直接返回 null 了。
request
在 null-safety 当中,命名参数 non-nullable 的类型必须要有默认值或是使用 request 关键字来修饰,也就是对于 non-nullable 来说它必须要有值。
List、Set、Map 中的 null-safety
在使用集合的时候需要考虑哪一部分是可以为 null 的。
List、 Set
Map
Map 情况与 List、Set类似, 但有个例外, 当通过 Key 拿 value 的时候,该 value 可能会为 null, 也就是说 map[‘key’] 返回的是一个 nullable
非健全的空安全
Dart 提供两种模式:
- 混合开发: 为了更加灵活,如果工程中有些库支持了 null-safety 而有些库没有,也是支持这种混合开发,称之为非健全的空安全(unsound null safety)。但当 safe 与 unsafe 的库互相混入无法在运行时保证完全健全,也就是说还是可能会报
NoSuchMethodError
相关错误。
直接升级到 Flutter 2.0 而没有迁移 App 就是 unsound null safety。
- 完全健全(建议):当所有的依赖所有的库全部都迁入 null-safety,此时即为健全的空安全。能够保证 null 的问题并且编译器可以进行优化使得程序更小更快。
迁移
迁移 app/package 前提:
- 等待: 等待工程中所有依赖都已经迁移至了 null-safety。
- 迁移: 使用迁移工具。
- 静态分析: 静态分析暴露出迁移后代码存在的问题,并做修复。
- 测试: 测试你的修改是可以运行的。
通过在 IDE 上增加一些 hit 来让工具实现预期的更改。
教程
DartPad 练习
Null safety feature tour(入门)
Understanding null safety(深入)
资料
DartPad 练习
参考资料
迁移指南
迁移视频
pub 迁移情况统计
Dart and the performance benefits of sound types
the known null safety issues fro Dart
the known null safety issues fro flutter