如何在构造函数体中初始化不可为空的成员? [英] How do I initialize non-nullable members in a constructor body?

查看:49
本文介绍了如何在构造函数体中初始化不可为空的成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以这种方式在 Dart 中创建了我的类,但是我得到了 非空实例字段文本"必须被初始化.尝试添加初始化表达式,或在此构造函数中添加字段初始化器,或将其标记为后期".有可能,提前谢谢你.

I've created my class in Dart this way, but I'm getting the Non-nullable instance field 'text' must be initialized. Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'. I would like to know if there's a way to do it in a 'Python' style where this kind of class creation is possible, thank you in advance.

class Lexer {
  String _text;
  int _pos;
  String _current_char;

  Lexer(String text) {
    this._text = text;
    this._pos = -1;
    this._current_char = '';
    this.advance();
  }

  void advance() {
    this._pos++;
    this._current_char = this._pos < this._text.length ? this._text[this._pos] : '';
  }
}

推荐答案

class Lexer {
  String _text;
  int _pos;
  String _current_char;

这声明了几个 String 类型的成员.由于它们被声明为String 而不是String?,因此这些成员不可为空;它们永远不能为 null.(这是 Dart 2.12 新的空安全特性的一部分.)

This declares several members with type String. Since they are declared as String and not as String?, these members are non-nullable; they are not allowed to ever be null. (This is part of the new null-safety feature from Dart 2.12.)

Dart 分两个阶段初始化对象.当构造函数的 body 运行时,Dart 期望所有成员变量都已经初始化.因为您的成员不可为空并且尚未初始化为非空值,所以这是一个错误.错误消息说明了您可以执行的操作:

Dart initializes objects in two phases. When the constructor's body runs, Dart expects all member variables to already be initialized. Because your members are non-nullable and haven't been initialized to non-null values yet, this is an error. The error message explains what you can do:

不可为空的实例字段 'text' 必须被初始化.尝试添加初始化表达式,或在此构造函数中添加字段初始化器,或将其标记为延迟".

Non-nullable instance field 'text' must be initialized. Try adding an initializer expression, or add a field initializer in this constructor, or mark it 'late'.

  • 使用初始化表达式.这意味着使用初始化列表:

    Lexer(String text)
      : _text = text,
        _pos = -1,
        _current_char = '' {
      advance();
    }
    

    请注意,如果您使用同名的构造参数初始化成员,则可以使用速记:

    Note that if you're initializing members with a construction parameter of the same name, you can use shorthand:

    Lexer(this._text)
      : _pos = -1,
        _current_char = '' {
      advance();
    }
    

  • 添加字段初始值设定项.这意味着在类声明中初始化成员内联.

    class Lexer {
      String _text = '';
      int _pos = -1,
      String _current_char = '';
    

  • 将您的成员标记为迟到.这意味着您承诺在任何尝试使用变量之前都会初始化这些变量.

  • Marking your members as late. This means that you promise that the variables will be initialized before anything attempts to use them.

    class Lexer {
      late String _text;
      late int _pos,
      late String _current_char;
    

  • 使您的成员可以为空,默认情况下允许它们隐式为空:

  • Making your members nullable, which allows them to be implicitly null by default:

    class Lexer {
      String? _text;
      int? _pos,
      String? _current_char;
    

    但是,我不建议这样做,因为这将要求所有访问在使用之前明确检查成员是否为空.

    However, I don't recommend that since that will require that all accesses explicitly check that the members aren't null before using them.

    您可能还想阅读:Dart 立即或在构造函数中分配给变量?

    这篇关于如何在构造函数体中初始化不可为空的成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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