Dart空安全非空类型规则与默认null值矛盾疑问求解
这两条规则完全不冲突,核心原因是非空类型的变量根本不允许出现「未初始化就被使用」的情况,你以为的「默认值为null」的场景,在非空类型上根本不会触发。
两条规则的适用边界
- 规则1(非空类型不可存储null):是Dart类型系统的强制约束,全场景生效,任何情况下非空类型的变量都不可能持有null值,编译、运行阶段会做双重校验拦截。
- 规则2(未初始化变量默认值为null):仅适用于可空类型的变量,非空类型的变量如果未初始化,会直接被编译器拦截,根本到不了读取默认值的运行阶段。
常见场景验证
- 普通非空类型变量未初始化
如果你直接编写如下代码:
int a; print(a);
编译阶段就会直接抛出错误:Non-nullable variable 'a' must be assigned before it can be used.,连运行的机会都没有,自然不会出现读取到默认null的情况。
late修饰的非空类型变量未初始化
如果你用late关键字向编译器保证「会在使用前给变量赋值」,编写了late int a;,如果后续未赋值就直接读取,运行时会直接抛出LateInitializationError,而不是返回null,依然不会违反非空类型的约束。可空类型变量未初始化
只有你声明为可空类型int? a;时,未初始化的情况下读取才会返回默认值null,这完全符合可空类型的规则,不存在冲突。
示例报错补充
你给出的示例代码int a=null; 报错的逻辑和上述规则一致:直接把null赋值给非空类型,编译器直接识别到违反类型约束,提前拦截。
类成员变量的额外说明
如果是非空的类成员变量,要么声明时直接赋值,要么在构造函数的初始化列表中赋值,要么用late修饰,否则编译同样不通过,不存在未初始化就被使用的可能。
内容的提问来源于stack exchange,提问作者Muhammad Afzal
相关产品推荐
相关产品推荐

