我正在升级一个基于Flutter框架的个人软件包。我注意到在Flutter Text小部件源代码中有一个null检查:
if (textSpan != null) {
properties.add(textSpan!.toDiagnosticsNode(name: 'textSpan', style: DiagnosticsTreeStyle.transition));
}
但是,textSpan!
仍然使用!
运算符。textSpan
不应该提升为不可空类型而不必使用!
操作符吗?但是,尝试删除操作符时会出现以下错误:
An expression whose value can be 'null' must be null-checked before it can be dereferenced.
Try checking that the value isn't 'null' before dereferencing it.
下面是一个自包含的示例:
class MyClass {
String? _myString;
String get myString {
if (_myString == null) {
return '';
}
return _myString; // <-- error here
}
}
我得到一个编译时错误:
错误:类型为“String?无法从函数“myString”返回“”,因为它的返回类型为“String”。
或者如果我尝试得到_mySting.length
,我会得到以下错误:
不能无条件访问属性“length”,因为接收器可以是“null”。
我以为做null检查会把_myString
提升为不可为null的类型。为什么不呢?
My question是在GitHub上解决的,所以我在下面发布了一个答案。
3条答案
按热度按时间jw5wzhpr1#
Dart工程师Erik Ernst在GitHub上说:
类型提升仅适用于局部变量。提升示例变量是不合理的,因为它可能被运行计算的getter重写,并且每次调用它时返回不同的对象。有关类似于类型提升但基于动态检查的机制的讨论,请参阅dart-lang/language#1188,并提供一些相关讨论的链接。
所以本地类型提升是有效的:
但示例变量不促进。为此,您需要手动告诉Dart,您确定示例变量在本例中不是null,方法是使用
!
操作符:zaqlnxep2#
错误:
假设,这是你的代码,你正在对示例变量进行null检查,仍然看到一个错误:
无法无条件调用方法“toDouble”,因为接收器可以为“null”。
您在这样的代码中看到的错误是因为Getter不会提升为不可空的对应项。让我们来谈谈为什么。
错误原因:
比如说,有一个类
Bar
,它扩展了Foo
并覆盖了x
字段,实现方式如下:如果你这么做了
您可能会遇到一个运行时空错误,这就是为什么禁止getters类型提升的原因。
解决方案:
我们需要抛弃
int?
的空性。通常有三种方法可以做到这一点。*使用局部变量(推荐)
*使用
?.
和??
*使用空Assert运算符(!)
只有在100%确定变量(
x
)永远不会是null
时,才应该使用此解决方案。xu3bshqb3#
style:Theme.of(context).textTheme.headline5!.copyWith(
尝试使用条件调用?或者一个无效的安全检查器!