Dart – 空安全
简单来说,Null 安全意味着一个变量不能包含“空”值,除非你用 null 初始化该变量。有了空安全,所有运行时空取消引用错误现在都将在编译时显示。
String name = null ; // This means the variable name has a null value.
例子 :
Dart
class Car {
String carName = "Aston Martin";
}
void main() {
Car cars;
print(cars.carName);
}
Dart
class Car {
String carName = "Aston Martin";
}
void main() {
Car cars = new Car();
print(cars.carName);
}
Dart
void main() {
int marks;
// The value of type `null` cannot be
// assigned to a variable of type 'int'
marks = null;
}
Dart
int checkValue(int? someValue) {
if (someValue == null) {
return 0;
}
// At this point the value is not null.
return someValue.abs();
}
void main(){
print(checkValue(5));
print(checkValue(null));
}
Dart
String? carName; // using ? operator
late String bikeName; // using "late" keyword
在上面的dart代码中,我们创建了一个类,并在其中初始化了一个名为 carName 的变量。在 main()函数,我们声明了一个变量类型汽车,即汽车。但是当我们运行上面的代码时,就会出现错误。
输出:
Error: Non-nullable variable 'cars' must be assigned before it can be used.
在上面的代码中,对象没有被初始化。为了解决这个问题,我们必须这样做:
Dart
class Car {
String carName = "Aston Martin";
}
void main() {
Car cars = new Car();
print(cars.carName);
}
输出:
Aston Martin
在上面的简单代码中,很容易识别哪个变量没有初始化,但在庞大的代码库中,识别此类错误可能非常困难且耗时。这个问题是由空安全解决的。
零安全原则
- 默认情况下不可为空:默认情况下, Dart变量不可为空,除非您明确指定它们可以为空。这是因为到目前为止,非 null 是 API 研究中最常见的选项。
- 逐步采用:迁移到空安全完全取决于您。您可以选择迁移到空安全的内容和时间。您可以增量迁移,在同一项目中组合空安全和非空安全代码。
- 完全可靠:由于 Dart 的空值安全性,编译器优化是可能的。如果类型系统确定某物不为空,则它不能为空。一旦您的整个项目及其依赖项迁移到空安全,空安全会导致更少的错误、更小的二进制文件和更快的执行。
不可为空的类型
当我们使用空安全时,默认情况下所有类型都是不可空的。例如,当我们声明一个 int 类型的变量时,该变量将包含一些整数值。
Dart
void main() {
int marks;
// The value of type `null` cannot be
// assigned to a variable of type 'int'
marks = null;
}
Non-nullable variables must always be initialized with non-null values.
可空类型
要指定变量是否可以为空,则可以使用可空类型运算符,让我们看一个例子:
String? carName; // initialized to null by default
int? marks = 36; // initialized to non-null
marks = null; // can be re-assigned to null
注意:您不需要在使用之前初始化可为空的变量。默认情况下,它被初始化为 null。
断言运算符 (!)
使用空断言运算符( ! ) 使Dart将可空表达式视为不可空表达式,如果您确定它不为空。
例子:
int? someValue = 30;
int data = someValue!; // This is valid as value is non-nullable
在上面的例子中,我们告诉Dart变量为空,将其分配给不可为空的变量是安全的,即
类型促销
Dart 的分析器会告诉您哪些编译时错误和警告,它足够智能,可以确定可空变量是否保证具有非空值。 Dart在运行时使用流分析进行类型提升(流分析是一种确定程序控制流的机制)。
例子:
Dart
int checkValue(int? someValue) {
if (someValue == null) {
return 0;
}
// At this point the value is not null.
return someValue.abs();
}
void main(){
print(checkValue(5));
print(checkValue(null));
}
在上面的代码中,if 语句检查值是否为空。在 if 语句之后,值不能为空,并被视为(提升)为不可为空的值。这使我们可以安全地使用代替 (使用空感知运算符)。这里函数将返回一个绝对值。
后期关键词
我们知道默认情况下所有变量都是非空的,我们可以使用 ?运算符或后期关键字。
例子:
Dart
String? carName; // using ? operator
late String bikeName; // using "late" keyword
空安全的好处:
- 它提供了一个更好的开发环境,运行时错误更少。
- Dart Compiler 可以优化我们的代码,这将导致程序更小更快。