空检查不会在Dart中引起类型提升 [英] Null check doesn't cause type promotion in Dart
问题描述
我正在升级基于Flutter框架的个人软件包.我注意到这里在Flutter Text小部件源代码中,存在空检查:
I'm upgrading a personal package that is based on the Flutter framework. I noticed here in the Flutter Text widget source code that there is a null check:
if (textSpan != null) {
properties.add(textSpan!.toDiagnosticsNode(name: 'textSpan', style: DiagnosticsTreeStyle.transition));
}
但是, textSpan!
仍在使用!
运算符.是否不必须使用!
运算符将 textSpan
提升为不可为空的类型?但是,尝试删除该运算符会出现以下错误:
However, textSpan!
is still using the !
operator. Shouldn't textSpan
be promoted to a non-nullable type without having to use the !
operator? However, trying to remove the operator gives the following error:
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
}
}
我收到一个编译时错误:
I get a compile-time error:
错误:类型为'String?'的值.无法从函数'myString'返回,因为它的返回类型为'String'.
Error: A value of type 'String?' can't be returned from function 'myString' because it has a return type of 'String'.
或者,如果我尝试获取 _mySting.length
,则会出现以下错误:
Or if I try to get _mySting.length
I get the following error:
不能无条件地访问属性"length",因为接收者可以为"null".
The property 'length' can't be unconditionally accessed because the receiver can be 'null'.
我认为执行null检查将把 _myString
提升为不可为null的类型.为什么不呢?
I thought doing the null check would promote _myString
to a non-nullable type. Why doesn't it?
我的问题已在GitHub上解决,因此我发布了答案在下面.
My question was solved on GitHub so I'm posting an answer below.
推荐答案
飞镖工程师Erik Ernst 在GitHub上的说法:
Dart engineer Erik Ernst says on GitHub:
类型提升仅适用于局部变量....实例变量的提升并不合理,因为它可能被运行计算的getter覆盖,并且每次调用它都会返回一个不同的对象.cf. dart-lang/language#1188 讨论与类型相似的机制促销,但基于动态检查,并带有相关讨论的链接.
Type promotion is only applicable to local variables. ... Promotion of an instance variable is not sound, because it could be overridden by a getter that runs a computation and returns a different object each time it is invoked. Cf. dart-lang/language#1188 for discussions about a mechanism which is similar to type promotion but based on dynamic checks, with some links to related discussions.
因此本地类型推广有效:
So local type promotion works:
String myMethod(String? myString) {
if (myString == null) {
return '';
}
return myString;
}
但是实例变量不提升.为此,您需要使用!
运算符手动告诉Dart您确保实例变量在这种情况下不为null:
But instance variables don't promote. For that you need to manually tell Dart that you are sure that the instance variable isn't null in this case by using the !
operator:
class MyClass {
String? _myString;
String myMethod() {
if (_myString == null) {
return '';
}
return _myString!;
}
}
这篇关于空检查不会在Dart中引起类型提升的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!