一、简介
空安全(Sound null safety)是 Dart 2.12 中新增的一项特性,空安全特性并不是 Dart 独有的,Kotlin, TypeScript, C#, Swift 等语言都有此特性,如果你了解这些语言的空安全特性及用法,那么下面关于 Dart 语言空安全特性的介绍你会感到非常熟悉,因为 Dart 语言空安全和其他语言基本一致。
版本要求
Dart 2.12和Flutter 2中提供了空安全性:
environment:
sdk: ">=2.12.0 <3.0.0"
二、基本使用
1、?(类型后面跟操作符 ? 表示当前变量可为null。)
int age = null; // 在没有空安全前,这句代码是没有问题的,
定义一个 int 类型的变量:
在没有空安全前,上面的代码是没有问题的,但当有了空安全后,在编译阶段出现异常,如下:
异常提示:null不能赋值给int变量。
:这是空安全与以前最大的不同,默认情况下,变量不能为null(空安全以前任何类型都可以设置为null),更重要的是此异常在编译阶段即出现,无法编译通过。
如果想给一个变量赋值 null 要如何处理?只需在类型后面添加 ? 即可,
如下:
int age = 1;
int? ageNull = null;
String? name = null;
其实也可以给值
int? ageNull = 0; // ?只是表示当前变量可为null。
类型后面跟操作符 ? 表示当前变量可为null。
输出 name 字符串的长度,此时会发现,无法编译通过,异常如下:
修改如下:
String? name = null;
print('name length:${name?.length}');
输出:
flutter: name length:null
注意:上面 name 为 null,调用 name?.length 不会抛出异常,而是返回 null。
2、!(在使用可为null的变量时对可为null变量的另一种处理方式)
:使用操作符 ! 要注意:如果无法确认变量不为null,千万不要使用操作符 !
String? name = null;
print('name length:${name!.length}');
上面的代码虽然可以编译通过,但运行时抛出异常,操作符
!
表示当前变量不为null
,开发者需要保证变量不为null
,否则会抛出异常。
三、在集合中
看如下List集合:
List list;
List? list1;
List list2;
List? list3;
他们的区别就是是否可为 null 的区别;
类型 | 集合是否可为null | item是否可为null |
---|---|---|
List | 否 | 否 |
List? | 是 | 否 |
List |
否 | 是 |
List |
是 | 是 |
Map 类型也是同理,Map 中的 key 一般不为 null,下面的 Item 指的是Map 中的 value:
类型 | 集合是否可为null | item是否可为null |
---|---|---|
Map |
否 | 否 |
Map |
是 | 否 |
Map |
否 | 是 |
Map |
是 | 是 |
四、方法参数
参数中加入了空安全,与变量用法一致。
void _incrementCounter(String? name) {
print('name length:${name?.length}');
}
五、class
定义一个类:
class Person{
final String? name;
Person(this.name);
}
那么下面的用法都是正确的:
//正确
var persion = Person(null);
//正确
var persion1 = Person('123');
六、初始化 late
假设有一个属性,此属性的值来源于服务器或者其他方法,那么此时无法给此属性进行初始化,代码如下:
提示我们必须要初始化,此情况使用关键字 late:
late String name;
但是,当使用此属性前 一定 要赋值,下面的用法运行时抛出异常:
late String name;
void _incrementCounter() {
print('name length:${name.length}');
}
正确用法:
late String name;
void _incrementCounter() {
name = '123';
print('name length:${name.length}');
}
总结
空安全增加了2个操作符 ?
和 !
,1个关键字 late
。
? :放在类型后面,表示当前变量可为null,例如 int a 和 int? b ,a 不能为null,而 b 可以。
! :放在变量后面,表示此变量值不为null,如果为null则会抛出异常。此操作符经常用于如下场景:一个方法的参数为非空类型(int),而传递给当前方法的变量是可为null的类型(int?),那么此时编译出现异常,在类型不变的情况下,在此变量的后面添加 ! ,表示当前变量不为null,代码如下:
int? b = 2;
int _add(int a){
return a+1;
}
//方法调用
_add(b!);
late:表示延迟初始化,通常用于延迟加载(比如网络请求),late 声明的变量在使用前一定要进行初始化。