Dart null安全不适用于类字段 [英] Dart null safety doesn't work with class fields

查看:55
本文介绍了Dart null安全不适用于类字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆