共计 5062 个字符,预计需要花费 13 分钟才能阅读完成。
本节指标
- 空平安意味着什么
- 如何迁徙代码
- 如何禁用空平安
- 代码标准示例
视频
https://www.bilibili.com/vide…
代码
https://github.com/ducafecat/…
参考
- https://dart.cn/null-safety
- https://dart.cn/null-safety/m…
- https://dart.cn/null-safety/u…
- https://dart.cn/null-safety/u…
- https://dart.cn/null-safety/faq
注释
空平安意味着什么
- 默认不可空
String title = 'ducafecat';
type?
操作符
String? title = null;
value!
操作符
String? title = 'ducafecat';
String newTitle = title!;
value?
操作符
String? title = 'ducafecat';
bool isEmpty = title?.isEmpty();
value??
操作符
String? title = 'ducafecat';
String newTitle = title ?? 'cat';
late
会在运行时查看。所以请您仅在确定它被应用前肯定会被初始化的状况下应用
late String? title;
title = 'ducafecat';
- List、泛型
类型 | 汇合是否可空 | 数据项是否可空 |
---|---|---|
List<String> | no | no |
List<String>? | yes | no |
List<String?> | no | yes |
List<String?>? | yes | yes |
- Map
类型 | 汇合是否可空 | 数据项是否可空 |
---|---|---|
Map<String, int> | no | no* |
Map<String, int>? | yes | no* |
Map<String, int?> | no | yes |
Map<String, int?>? | yes | yes |
*
可能返回空
// 有可能返回 null
int value = <String, int>{'one': 1}['one']; // ERROR
// 须要加上 type?
int? value = <String, int>{'one': 1}['one']; // OK
// 或者 value!
int value = <String, int>{'one': 1}['one']!; // OK
带来的益处
- 代码更衰弱
- 用户体验好
- 运行更快
- 编译文件更小
开启和迁徙
- pubspec.yaml
environment:
sdk: ">=2.12.0 <3.0.0"
- 迁徙程序
咱们强烈建议您按程序迁徙代码,先迁徙依赖关系中的处于最末端的依赖。例如,如果 C 依赖了 B,B 依赖了 A,那么应该依照 A -> B -> C 的程序进行迁徙。
- 查看依赖我的项目
# Dart 版本是否为 2.12 或更高
> dart --version
# 依赖包的迁徙状态
> dart pub outdated --mode=null-safety
- 降级依赖
# 该命令会更改您的 pubspec.yaml 文件
> dart pub upgrade --null-safety
# 升级包
> dart pub upgrade
- 迁徙工具
> dart migrate
- 剖析
> dart analyze
禁用空平安
- cli 命令
> dart --no-sound-null-safety run
> flutter run --no-sound-null-safety
- .vscode/launch.json
{
// 应用 IntelliSense 理解相干属性。// 悬停以查看现有属性的形容。// 欲了解更多信息,请拜访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "getx_quick_start",
"request": "launch",
"type": "dart",
"program": "lib/main.dart",
"args": ["--no-sound-null-safety"]
}
]
}
范例、标准
https://dart.cn/null-safety/u…
- 明确解决空状态
makeCoffee(String coffee, [String? dairy]) {if (dairy != null) {print('$coffee with $dairy');
} else {print('Black $coffee');
}
}
- 顶层变量和动态字段必须蕴含一个初始化办法。 因为它们能在程序里的任何地位被拜访到,编译器无奈保障它们在被应用前已被赋值。惟一保险的选项是要求其自身蕴含初始化表达式,以确保产生匹配的类型的值。
int topLevel = 0;
class SomeClass {static int staticField = 0;}
- 实例的字段也必须在申明时蕴含初始化办法,能够为常见初始化模式,也能够在实例的构造方法中进行初始化。
class SomeClass {
int atDeclaration = 0;
int initializingFormal;
int initializationList;
SomeClass(this.initializingFormal)
: initializationList = 0;
}
- 局部变量的灵便度最高。一个非空的变量 不肯定须要 一个初始化办法。
int tracingFibonacci(int n) {
int result;
if (n < 2) {result = n;} else {result = tracingFibonacci(n - 2) + tracingFibonacci(n - 1);
}
print(result);
return result;
}
- 流程剖析,在这里 Dart 将
object
的类型从它申明的Object
晋升到了List
。在空平安引入以前,上面的程序无奈运行。
// With (or without) null safety:
bool isEmptyList(Object object) {if (object is List) {return object.isEmpty; // <-- OK!} else {return false;}
}
->
// Without null safety:
bool isEmptyList(Object object) {if (object is! List) return false;
return object.isEmpty;
}
- 相对的赋值剖析
int tracingFibonacci(int n) {
final int result;
if (n < 2) {result = n;} else {result = tracingFibonacci(n - 2) + tracingFibonacci(n - 1);
}
print(result);
return result;
}
- 无用代码的正告
String checkList(List list) {if (list?.isEmpty) {return 'Got nothing';}
return 'Got something';
}
- 懒加载的变量,
late
修饰符是“在运行时而非编译时对变量进行束缚”。这就让late
这个词语约等于 何时 执行对变量的强制束缚。
// Using null safety:
class Coffee {
String? _temperature;
void heat() { _temperature = 'hot';}
void chill() { _temperature = 'iced';}
String serve() => _temperature! + 'coffee';}
->
// Using null safety:
class Coffee {
late String _temperature;
void heat() { _temperature = 'hot';}
void chill() { _temperature = 'iced';}
String serve() => _temperature + 'coffee';}
late
与final
联合应用,与一般的final
字段不同,您不须要在申明或结构时就将其初始化。您能够稍后在运行中的某个中央加载它。然而您只能对其进行 一次 赋值,并且它在运行时会进行校验。
// Using null safety:
class Coffee {
late final String _temperature;
void heat() { _temperature = 'hot';}
void chill() { _temperature = 'iced';}
String serve() => _temperature + 'coffee';}
- 毕传参数,这里的所有参数都必须通过命名来传递。参数
a
和c
是可选的,能够省略。参数b
和d
是必须的,调用时必须传递。在这里请留神,是否必须和是否可空无关。
// Using null safety:
function({int? a, required int? b, int? c, required int? d}) {}
- 形象字段
abstract class Cup {
Beverage get contents;
set contents(Beverage);
}
->
abstract class Cup {abstract Beverage contents;}
- 一些赋值计算能够挪动到动态的初始化中。
// Initalized without values
ListQueue _context;
Float32List _buffer;
dynamic _readObject;
Vec2D(Map<String, dynamic> object) {_buffer = Float32List.fromList([0.0, 0.0]);
_readObject = object['container'];
_context = ListQueue<dynamic>();}
->
// Initalized with values
final ListQueue _context = ListQueue<dynamic>();
final Float32List _buffer = Float32List.fromList([0.0, 0.0]);
final dynamic _readObject;
Vec2D(Map<String, dynamic> object) : _readObject = object['container'];
- 可能返回
null
的工厂办法
factory StreamReader(dynamic data) {
StreamReader reader;
if (data is ByteData) {reader = BlockReader(data);
} else if (data is Map) {reader = JSONBlockReader(data);
}
return reader;
}
->
factory StreamReader(dynamic data) {if (data is ByteData) {
// Move the readIndex forward for the binary reader.
return BlockReader(data);
} else if (data is Map) {return JSONBlockReader(data);
} else {throw ArgumentError('Unexpected type for data');
}
}
© 猫哥
本视频文档
https://ducafecat.tech/2021/0…
GetX Quick Start 代码
https://github.com/ducafecat/…
新闻客户端代码
https://github.com/ducafecat/…
strapi 手册译文
https://getstrapi.cn
微信探讨群 ducafecat
往期视频
- Dart 编程语言根底
https://space.bilibili.com/40… - Flutter 零根底入门
https://space.bilibili.com/40… - Flutter 实战从零开始 新闻客户端
https://space.bilibili.com/40… - Flutter 组件开发
https://space.bilibili.com/40… - Flutter 组件开发
https://space.bilibili.com/40… - Flutter Bloc
https://space.bilibili.com/40… - Flutter Getx4
https://space.bilibili.com/40… - Docker Yapi
https://space.bilibili.com/40…
正文完