空安全

flutter空安全相关内容

Author: huyikai

flutter空安全

空安全的原则

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

  1. 默认不可空:除非你将变量显式声明为可空,否则它一定是非空的类型;

  2. 渐进迁移:你可以自由地选择何时进行迁移,多少代码会进行迁移;

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

移入空安全前后 Dart 类型系统的变化

在引入空安全前 Dart 的类型系统是这样的:

img

这意味着在之前,所有的类型都可以为 null,也就是 null 类型被看作是所有类型的子类。

在引入空安全后:

img

可以看出,最大的变化是将 null 类型独立出来了。这意味着 null 不再是其它类型的子类,所以对于一个非 null 类型的变量传递一个 null 值时会报类型转换错误。

提示:在使用了空安全的 Flutter 或 Dart 项目中你会经常看到 ?.!.late 的大量应用,它们分别是什么又该如何使用呢?请看下文分析

可空(?)类型的使用

我们可以通过将 ? 跟在类型的后面来表示它后面的变量或参数可接受 Null

class CommonModel {
String? firstName; //可空的成员变量
int getNamelen(String? lastName /*可空的参数*/){
int firstLen = firstName?.length ?? 0;
int lastLen = lastName?.length ?? 0;
return firstLen + lastLen;
}
}

对于可空的变量或参数在使用的时候需要通过 Dart 的避空运算符 ?. 来进行访问,否则会抛出编译错误。

当程序启用空安全后,类的成员变量默认是不可空的,所以对于一个非空的成员变量需要指定其初始化方式:

class CommonModel {
List names = [];//定义时初始化
final List colors;//在构造方法中初始化
late List urls;//延时初始化
CommonModel(this.colors);
}

延迟初始化(late)的使用

对于无法再定义时进行初始化,并且又想避免使用 ?.,那么延迟初始化可以帮到你。通过 late 修饰的变量,可以让开发者选择初始化的时机,并且在使用跟这个变量时可以不用 ?.

late List urls;//延时初始化
setUrls(List urls){
this.urls = urls;
}
int getUrlLen(){
return urls.length;
}

延时初始化虽然能为我们编码带来一定便利,但如果使用不当会带来空异常的问题,所以在使用的时候一定保证赋值和访问的顺序

空值断言操作符(!)的使用

当我们排除变量或参数的可空的可能后,可以通过 ! 来告诉编译器这个可空的变量或参数不可空,这对我们进行方法传参或将可空参数传递给一个不可空的入参时特别有用。