Dart SDK,2.12之前的都不是空安全的,2.12之后都是空安全的。
如何查看项目中哪些依赖没有支持空安全?
以这个项目为例:使用Android Studio 打开starter项目
在starter项目中执行下面命令查看:
dart pub outdated --mode=null-safety
打印如下:
└─[0] <> dart pub outdated --mode=null-safety
Showing dependencies that are currently not opted in to null-safety.
[✗] indicates versions without null safety support.
[✓] indicates versions opting in to null safety.
Package Name Current Upgradable Resolvable Latest
direct dependencies:
intl ✗0.16.1 ✗0.16.1 ✓0.18.0 ✓0.18.0
1 dependency is constrained to a version that is older than a resolvable version.
To update it, edit pubspec.yaml, or run `dart pub upgrade --null-safety`.
执行完命令,将会显示intl库没有支持空安全,✗0.16.1 这个是不支持空安全的版本,✓0.18.0是支持空安全的版本
在pubspec.yaml文件中找到对应的库,设置为支持空安全的版本号
//不支持空安全
dependencies:
flutter:
sdk: flutter
intl: ^0.16.1
//支持空安全
dependencies:
flutter:
sdk: flutter
intl: ^0.18.0
修改后然后执行 flutter pub upgrade
注意:目前这个项目中只有一个依赖库intl,如果存在多个依赖库,如果 C 依赖了 B,B 依赖了 A,那么应该按照 A -> B -> C 的顺序进行迁移。
如何合并空安全?
执行下面命令:
dart migrate
打印如下:
─[0] <> dart migrate
Migrating /Users/zhouluyao/Downloads/video-dns-materials-versions-1.0/06-migrate-to-null-safe-code/starter
See https://dart.dev/go/null-safety-migration for a migration guide.
Analyzing project...
[----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------/]No analysis issues found.
Generating migration suggestions...
[-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------]
Compiling instrumentation information...
[-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------]
View the migration suggestions by visiting:
http://127.0.0.1:62907/Users/zhouluyao/Downloads/video-dns-materials-versions-1.0/06-migrate-to-null-safe-code/starter?authToken=5FVRDl8f1Ec%3D
Use this interactive web view to review, improve, or apply the results.
When finished with the preview, hit ctrl-c to terminate this process.
If you make edits outside of the web view (in your IDE), use the 'Rerun from
sources' action.
1、在浏览器里面浏览这个链接,效果如下图(注意这个是我调试的链接,需要在上面的打印中,找到你的项目控制台打印的链接进行浏览) http://127.0.0.1:62907/Users/zhouluyao/Downloads/video-dns-materials-versions-1.0/06-migrate-to-null-safe-code/starter?authToken=5FVRDl8f1Ec%3D
2、需要提示的是,现在项目中的代码还没有改变,目前在浏览器查看的只是一些修改建议
3、你检查过之后没有问题了,可以点击上方的按钮,APPLY MIGRATE修改代码
具体讲解一下项目中的空安全用法:
服务器返回的JSon格式如下,可以看到第一、第三个国家的Json信息中,population字段、currencyCode字段没有返回,也就是说这两个字段是可空的
{
"countries": [
{
"countryCode": "AD",
"countryName": "Andorra",
"currencyCode": "EUR",
"capital": "Andorra la Vella",
"continentName": "Europe"
},
{
"countryCode": "AE",
"countryName": "United Arab Emirates",
"currencyCode": "AED",
"population": "4975593",
"capital": "Abu Dhabi",
"continentName": "Asia"
},
{
"countryCode": "AF",
"countryName": "Afghanistan",
"population": "29121286",
"capital": "Kabul",
"continentName": "Asia"
},]
}
下面的注释是项目中的一些具体修改建议
class Country {
late final String countryCode; //如果一个final 变量没有被赋值,会报final 变量需要initialize的错误,需要把final变量使用late修饰,在使用它之前对他进行设置
late final String countryName;
String? currencyCode; //服务器返回的Json字段可能缺少,需要使用String?
String? population;
late final String capital;
late final String continentName;
Country(
{required this.countryCode,
//this.countryName,(修改前)这样写countryName就是option类型的,我们不允许可选参数在这,因为这个final变量是非空的,解决办法是在初始化变量的前面加上require关键字
required this.countryName,
required this.currencyCode,
required this.population,
required this.capital,
required this.continentName});
Country.fromMap(Map<String, dynamic> map) {
countryCode = map['countryCode'] as String;
countryName = map['countryName'] as String;
currencyCode = map['currencyCode'] as String?; //如果服务器返回的json缺少该字段,或者该字段为空,需要转换成String?
population = map['population'] as String?;
capital = map['capital'] as String;
continentName = map['continentName'] as String;
}
}
//对于可选类型的值可以给一个默认值
var population = country.population ?? "";
//对空值进行默认处理
String formatPopulation(String? population) {
final format = NumberFormat.compact(locale: 'it-it');
population ??= '0';
final number = int.parse(population);
return format.format(number);
}