Dart:空安全-null-safe

空安全的核心思想

**Dart 的空安全(null safety)**是 Dart 2.12 开始引入的重要特性,能让你的程序更安全地处理 null,减少运行时空指针错误(NullPointerException)。

核心思想:“非空即安全,空值要声明”

在空安全模式下:

  • 变量默认非空int x = 5; 表示 x 永远不可能为 null
  • 需要允许 null 时必须显式声明int? x; 才表示 x 可以为 null

非空类型与可空类型

类型写法 含义
int 不能为 null
int? 可以为 null

示例

void main() {
  int a = 5;      // ✅ 非空
  // a = null;    // ❌ 编译报错:非空变量不能赋 null

  int? b;         // ✅ 可空
  b = null;       // ✅
}

检查 null 的几种方式

if 判断

int? b;
if (b != null) {
  print(b + 1); // 编译器知道 b 不为 null 了
}

条件访问 ?.

String? name;
print(name?.length); // 如果 name 为 null,返回 null,不会抛异常

默认值 ??

String? name;
print(name ?? '默认名字'); // name 为 null 时用默认值

默认赋值 ??=

String? name;
name ??= '默认名字'; // 如果 name 为 null,则赋值

非空断言 !(谨慎)

String? name;
print(name!.length); // 断言 name 一定不为 null,否则运行时抛异常

延迟初始化(late

空安全要求变量初始化前就必须有值。如果你确定稍后会赋值,可以用 late

late String name;
name = 'Dart';
print(name); // OK

注意:如果 late 变量在使用前没赋值,会抛运行时错误。

class WPHttpService extends GetxService {
  late final Dio _dio;

  @override
  void onInit() {
    ...

    _dio = Dio(options);

    ...
  }

加上 late 后就可以不用构造函数的时候初始化了

可空类型和方法返回值

String? findUser(int id) {
  if (id == 1) return 'Alice';
  return null; // 返回 null 是允许的
}

void main() {
  String? user = findUser(2);
  print(user ?? '未知用户');
}

类型提升(null check promotion)

Dart 会在检查变量非空后,自动把类型从 T? 提升为 T

void printLength(String? text) {
  if (text != null) {
    // 这里 text 类型变成 String(非空)
    print(text.length);
  }
}

8. 小结对照表

语法 作用
T? 声明可空类型
?. 只有非空才访问成员
?? 可空时用默认值
??= 为空时赋默认值
! 断言不为空(风险)
late 延迟初始化

集合与空安全

list

List<String?>? l;
l = [];
l.add(null);
l.add('a');
print(l);
类型 集合是否可空 数据项是否可空
List<String> no no
List<String>? yes no
List<String?> no yes
List<String?>? yes yes

Map

Map<String, String?>? m;
m = {};
m['a'] = 'b';
m['b'] = null;
print(m);
类型 集合是否可空 数据项是否可空
Map<String, int> no no*
Map<String, int>? yes no*
Map<String, int?> no yes
Map<String, int?>? yes yes

* :表示可能返回空


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1909773034@qq.com

×

喜欢就点赞,疼爱就打赏