Dart null安全不适用于类字段 [英] Dart null safety doesn't work with class fields
问题描述
我已将Dart代码迁移到NNBD/空安全.其中一些看起来像这样:
I have migrated my Dart code to NNBD / Null Safety. Some of it looks like this:
class Foo {
String? _a;
void foo() {
if (_a != null) {
_a += 'a';
}
}
}
class Bar {
Bar() {
_a = 'a';
}
String _a;
}
这将导致两个分析错误.对于 _a + ='a';
:
This causes two analysis errors. For _a += 'a';
:
其值可以为'null'的表达式必须先进行空检查,然后才能将其取消引用.取消引用之前,请尝试检查该值是否为'null'.
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.
对于 Bar(){
:
不可初始化的实例字段'_a'必须被初始化.尝试添加一个初始化程序表达式,或在此构造函数中添加一个字段初始化程序,或将其标记为"late".
Non-nullable instance field '_a' must be initialized. Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.
在两种情况下,我已经完全按照错误提示进行了操作!这是怎么回事?
In both cases I have already done exactly what the error suggests! What's up with that?
我正在使用Dart 2.12.0-133.2.beta(星期二12月15日).
I'm using Dart 2.12.0-133.2.beta (Tue Dec 15).
我找到了此页面,其中说:
分析器无法对整个应用程序的流程进行建模,因此无法预测全局变量或类字段的值.
The analyzer can’t model the flow of your whole application, so it can’t predict the values of global variables or class fields.
但这对我来说没有意义-从 if(_a!= null)
到 _a + ='a';
在这种情况下-没有异步代码,Dart是单线程的-因此 _a
不在本地也没关系.
But that doesn't make sense to me - there's only one possible flow control path from if (_a != null)
to _a += 'a';
in this case - there's no async code and Dart is single-threaded - so it doesn't matter that _a
isn't local.
Bar()
的错误消息明确指出了在构造函数中初始化字段的可能性.
And the error message for Bar()
explicitly states the possibility of initialising the field in the constructor.
推荐答案
问题是,即使将类字段标记为 final
,也可以覆盖类字段.下面的示例说明了该问题:
The problem is that class fields can be overridden even if it is marked as final
. The following example illustrates the problem:
class A {
final String? text = 'hello';
String? getText() {
if (text != null) {
return text;
} else {
return 'WAS NULL!';
}
}
}
class B extends A {
bool first = true;
@override
String? get text {
if (first) {
first = false;
return 'world';
} else {
return null;
}
}
}
void main() {
print(A().getText()); // hello
print(B().getText()); // null
}
B
类将覆盖 text
最终字段,因此它在首次被请求时返回一个值,但此后返回 null
.您不能以防止阻止这种形式的覆盖的方式编写 A
类.
The B
class overrides the text
final field so it returns a value the first time it is asked but returns null
after this. You cannot write your A
class in such a way that you can prevent this form of overrides from being allowed.
因此,即使看起来像我们检查了 text,我们也无法将
getText
的返回值从 String?
更改为 String
字段,返回 null
.
So we cannot change the return value of getText
from String?
to String
even if it looks like we checks the text
field for null
before returning it.
这篇关于Dart null安全不适用于类字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!