📜  Dart – 空安全

📅  最后修改于: 2022-05-13 01:54:58.437000             🧑  作者: Mango

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变量someValue   为空,将其分配给不可为空的变量是安全的,即data

类型促销

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 语句之后,值不能为空,并被视为(提升)为不可为空的值。这使我们可以安全地使用someValue.abs()   代替someValue?.abs()   (使用空感知运算符)。这里.abs()   函数将返回一个绝对值。

后期关键词

我们知道默认情况下所有变量都是非空的,我们可以使用 ?运算符或后期关键字。

例子:

Dart

String? carName;       // using ? operator
late String bikeName;  // using "late" keyword

空安全的好处:

  • 它提供了一个更好的开发环境,运行时错误更少。
  • Dart Compiler 可以优化我们的代码,这将导致程序更小更快。