Flutter2.0 强大的空安全

简介

空安全(Sound null safety)是 Dart 2.12 中新增的一项特性,空安全特性并不是 Dart 独有的,Kotlin, TypeScript,  C#, Swift 等语言都有此特性,如果你了解这些语言的空安全特性及用法,那么下面关于 Dart 语言空安全特性的介绍你会感到非常熟悉,因为 Dart 语言空安全和其他语言基本一致。

版本要求

Dart 2.12和Flutter 2中提供了空安全性,对应到Flutter项目中,则需要在pubspec.yaml文件中添加如下配置:

environment:
  sdk: ">=2.12.0 <3.0.0"

基本使用

变量

定一个 int 类型的变量,

int age = null;

在没有空安全前,上面的代码是没有问题的,但当使用空安全后,在编译阶段出现异常,如下:

异常提示:null不能赋值给int变量。

这是空安全与以前最大的不同,默认情况下,变量不能为null(空安全以前任何类型都可以设置为null),更重要的是此异常在编译阶段即出现异常,无法编译通过。

如果想给一个变量赋值 null 要如何处理?只需在类型后面添加 ? 即可,如下:

  int age = 1;
  int? ageNull = null;
  String? name = null;

类型后面跟操作符 ? 表示当前变量可为null。

变量的使用:

String? name = null;
print('name length:${name?.length}');

非常简单,输出 name 字符串的长度,此时会发现,无法编译通过,异常如下:

修改如下:

String? name = null;
print('name length:${name?.length}');

输出:

flutter: name length:null

注意:上面 name 为 null,调用 name?.length 不会抛出异常,而是返回 null。

还可以有另外一种方式处理上面的异常:使用操作符  !

String? name = null;
print('name length:${name!.length}');

上面的代码虽然可以编译通过,但运行时抛出异常,操作符  ! 表示检测当前变量不为 null,开发者需要保证变量不为 null,否则会抛出异常。

如果无法确认变量不为null,千万不要使用操作符  !

集合

看如下List集合:

List<String> list;
List<String>? list1;
List<String?> list2;
List<String?>? list3;

他们的区别就是是否可为 null 的区别,List 表示 List 不为 null 而且集合中的 Item 也不能为 null。那么如下代码就是错误的:

List<String> list;
//错误
list = null;
list.add(null);

List 集合说明如下:

类型集合是否可为nullItem 是否可以为null
List
List?
List<String?>
List<String?>?

Map 类型也是同理,Map 中的 key 一般不为 null,下面的 Item 指的是Map 中的 value:

类型集合是否可为nullItem 是否可以为null
Map<String,String>
Map<String,String>?
Map<String,String?>
Map<String,String?>?

方法参数

void _incrementCounter(String? name) {
  print('name length:${name?.length}');
}

上面方法参数中加入了空安全,与变量用法一致。

class

定义一个类:

class Person{
  
  final String name;

  Person(this.name);
}

有一个属性 name,属性类型为 String,说明此属性不能为 null,下面的使用是错误的:

//错误,无法编译通过
var persion = Person(null);
//正确
var persion1 = Person('123');

将属性 name 改为可为 null:

class Person{

  final String? name;

  Person(this.name);
}

那么下面的用法都是正确的:

//正确
var persion = Person(null);
//正确
var persion1 = Person('123');

初始化 late

假设有一个属性,此属性的值来源于服务器或者其他方法,那么此时无法给此属性进行初始化,代码如下:

String name;

此时会编译异常:

图片

image-20210331172618734

提示我们必须要初始化,此情况使用关键字 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 声明的变量在使用前一定要进行初始化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter 2.0 之后,Dart 默认启用了安全(Null Safety),因此在使用二维码扫描插件时需要使用安全的 API。 对于 `qr_code_scanner` 插件,可以使用 `qr_code_scanner_nullsafety` 包,其使用方式与原始插件基本相同,只是 API 有所改变。以下是一个简单的示例: 1. 添加 `qr_code_scanner_nullsafety` 插件到 `pubspec.yaml` 文件中: ``` dependencies: qr_code_scanner_nullsafety: ^0.5.2 ``` 2. 导入 `qr_code_scanner_nullsafety` 包: ``` import 'package:qr_code_scanner_nullsafety/qr_code_scanner_nullsafety.dart'; ``` 3. 创建一个 `QRViewController` 和一个 `QRView`: ``` QRViewController? controller; final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); @override Widget build(BuildContext context) { return QRView( key: qrKey, onQRViewCreated: _onQRViewCreated, ); } void _onQRViewCreated(QRViewController newController) { controller = newController; controller!.scannedDataStream.listen((scanData) { // 处理扫描到的二维码 }); } ``` 注意,`QRViewController` 类型需要加上问号 `?`,表示这个对象可能为。在 `_onQRViewCreated()` 方法中,也需要对 `controller` 进行非判断,确保它不为。 对于 `barcode_scan` 插件,可以使用 `barcode_scan_null_safety` 包,使用方式与原始插件类似。以下是一个简单的示例: 1. 添加 `barcode_scan_null_safety` 插件到 `pubspec.yaml` 文件中: ``` dependencies: barcode_scan_null_safety: ^2.0.1 ``` 2. 导入 `barcode_scan_null_safety` 包: ``` import 'package:barcode_scan_null_safety/barcode_scan_null_safety.dart'; ``` 3. 调用 `scan()` 方法并处理返回的数据: ``` Future<void> scan() async { String barcode = await BarcodeScanner.scan(); // 处理扫描到的二维码 } ``` 对于 `barcode_scan_null_safety`,`scan()` 方法返回的类型为非的 `Future<String>`,不需要进行值检查。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值