📌  相关文章
📜  Flutter:不健全的 null 安全性 (1)

📅  最后修改于: 2023-12-03 15:00:49.267000             🧑  作者: Mango

Flutter:不健全的 null 安全性

简介

Flutter 是一种流行的开源框架,用于构建跨平台的高性能移动应用程序。Flutter 具有许多强大的功能,例如快速开发、热重载、丰富的小部件库和强大的性能。

然而,在 Flutter 的 null 安全性方面存在一些挑战。即使 Flutter 2.0 引入了空安全(null safety)功能,但是在某些情况下,空安全性仍然不够健全。本文将探讨 Flutter 的空安全性问题,并提供解决方案。

Flutter 的 null 安全性问题
可空类型

在 Dart 中,可空类型是指一个变量可以存储 null 值。可空类型可以使用 ? 修饰符来定义。例如:

int? nullableInt;

在 Flutter 中,可空类型是非常常见的。实际上,Flutter 的许多小部件都可以使用可空类型来进行配置。例如:

Text? nullableText;

可空类型带来的问题是:在使用可空类型的变量时,必须显式地在代码中处理 null 值的情况。否则,代码将会出现空指针异常。例如:

if (nullableText != null) {
  print(nullableText!.text);
} else {
  print('Text is null');
}

上述代码检查了 nullableText 是否为 null。如果不为 null,则打印 nullableText.text 的值。否则,打印 'Text is null'。

非空断言

对于可空类型,Dart 提供了一个非空断言操作符(!)。该操作符表示:“我知道这个变量不是 null”。例如:

int? nullableInt = 5;
int nonNullableInt = nullableInt!;

在上述代码中,nullableInt! 表示我们允许将 nullableInt 强制转换为非空类型,因为我们知道它不是 null。

然而,在 Flutter 中,非空断言带来的问题是:如果我们错误地对 null 进行非空断言,则会导致应用程序崩溃。例如:

Text? nullableText;
print(nullableText!.text);

上述代码中,nullableText!.text 表示我们允许将 nullableText 强制转换为非空类型,但实际上 nullableText 是 null,因此会导致应用程序崩溃。

多次非空断言

在 Flutter 中,许多小部件都允许使用链式表达式。例如:

Text(
  'Hello',
  style: TextStyle(color: Colors.blue, fontSize: 18),
),

在上述代码中,TextStyle 对象是通过链式表达式构建的。但是,如果我们尝试对一个可空类型多次使用非空断言,则会导致异常。例如:

Text? nullableText;
print(nullableText!.style!.color);

上述代码中,我们尝试使用两次非空断言,但实际上 nullableTextnullableText.style 可能为 null。

解决方案

为了避免 Flutter 中 null 安全性问题,我们可以采用以下解决方案:

使用 Null-Safe 代码

Flutter 2.0 引入了空安全性(null safety)功能。空安全代码可在运行时捕获 null 异常,并提供更加健全的 null 安全性。因此,我们应该尽可能地使用 Null-Safe 代码来构建我们的应用程序。

使用三元运算符

当需要验证可空类型时,我们可以使用三元运算符来代替 if 语句。例子如下:

Text? nullableText;
final text = nullableText?.text ?? 'Text is null';
print(text);

在上例中,nullableText?.text 表示:如果 nullableText 不为 null,则返回 nullableText.text 的值。否则,返回 null。?? 运算符表示:如果左侧表达式为 null,则返回右侧表达式的值。因此,我们可以使用三元运算符来处理 null 值,而不需要显式地进行 if-null 检查。

避免多次非空断言

当使用多次非空断言时,我们应该确保在每个断言前进行 if-null 检查。例子如下:

Text? nullableText;
if (nullableText != null && nullableText.style != null) {
  print(nullableText.style.color);
} else {
  print('Text or style is null');
}

在上例中,我们首先检查 nullableText 是否为 null,然后再检查 nullableText.style 是否为 null。这样可以避免出现多次非空断言的情况。

结论

尽管 Flutter 2.0 引入了空安全性功能,但在某些情况下,空安全性仍然不够健全。在 Flutter 中,我们应该避免使用多次非空断言,并尽可能地使用 Null-Safe 代码来构建我们的应用程序。使用这些解决方案,我们可以更好地管理 null 值,并提高代码的健全性。