浅谈 Flutter 空安全

介绍

空安全(Sound null safety)是Flutter 更新之后 Dart 中新增的一项特性,它并不是独有的,像Kotlin、swift等语言也有此特性。有了空安全,Dart 分析器可以进行更好的检查。例如:它将在您读取一个可空的变量前提示您进行空检查。由于 Dart 的空安全是十分有效的, Dart 编译器和运行环境也同时可以通过优化减少内部的空安全检查, 这样应用就可以更快且更小。与空安全相关的新操作符和关键字有 ?、!。如果之前有了解过的话相信接下来很容易能明白,因为它们之间的代码非常一致。

使用

我们先看一个简单的代码,定义一个int 类型的变量

int count = null;

在没有空安全前,上面的代码是可以编译的,不会报错,在有空安全之后,我们看看编译时的异常:
在这里插入图片描述
异常提示:int类型不能赋值为null类型。
在空安全之前,是可以直接赋值为null,且可以通过编译,这个就说空安全与之前最大的不同,而且是在编译阶段就直接报异常错误。
在使用空安全的情况下,我们想让变量赋值为null时,我们可以这样处理:

 int? count = null;
 String? name = null;

只需在类型后面添加 ? 即可
类型后面跟操作符 ? 表示当前变量可为null。

使用过程容易出现的问题

我们接下来来看看平时日常中使用空安全比较容易出现的问题。我们下面看一段简单的代码:

String? name = null;
print('name的长度================${name.length}');

这段代码会出现编译异常:
在这里插入图片描述
异常的大概意思是我们定义了可以为null的变量,无法直接进行使用。
我们可以将上面代码改为:

String? name = null;
print('name的长度================${name?.length}');

输出的值为 name的长度================null.
因为我们前面定义了该变量可以为null,所以不会抛出异常,正常返回null。
我们可以看到之前的编译异常,提示可以使用 ?或 !进行空检查。现在我们试试另外一个操作符 !看看会是什么效果:

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

运行之后,我们发现,虽然编译通过,但是运行报错。
操作符!表示当前变量不为null,但是上面的代码是为null的,所以运行时出现了异常。所以这里我们需要格外注意的是:

如果变量无法确定不为null,请不要使用 !操作符。

接下来我们看看类中空安全的使用场景,我们定义简单的一个class:

class Student {
  int age;
  Student(this.age);
}

接下来是使用:

void Test(){
    var student = Student(10);//编译通过
    var student2 = Student(null);//无法编译通过
  }

我们需要改成如下:

class Student {
  int? age;
  Student(this.age);
}

下面的代码就能正常编译了:

var student2 = Student(null);//编译通过

常用场景

在使用空安全的时候,我个人总结一下在平时经常遇到的场景:一个方法的参数为非空类型,而传递给当前方法的变量是可为null的类型,那么此时编译出现异常,在类型不变的情况下,在此变量的后面添加 ! ,表示当前变量不为null,可以看下下面的代码:

String? name = "Hello";

int _getLength(String name){
  return name.length;
}

//方法调用
_getLength(name!);

这时候的使用我们需要留意一下。

总结

今天的总结其实就只有一句话,
操作符 ? :放在类型后面表示当前变量可为null,例如 String a 和 String ? b ,a 不能为null,而 b 可以。
操作符 !:表示此变量值不为null,如果为null则会抛出异常。使用请慎重考虑。
共勉~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
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>`,不需要进行值检查。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值