【问题标题】:Dart - initializing final class members depedent on each otherDart - 初始化相互依赖的最终类成员
【发布时间】:2022-01-11 19:57:49
【问题描述】:

我喜欢在有意义的时候在我的类中使用 final 成员,但是我在尝试做一些相对简单的事情时遇到了问题:

import 'dart:ui';

class Foo {
  final PictureRecorder recorder;
  final Canvas canvas;
  final int margin;

  Foo({
    this.margin = 10,
  })  : recorder = PictureRecorder(),
        canvas = Canvas(recorder) { // this line errors out
  }
}

我从编译器得到的错误是:

The instance member 'recorder' can't be accessed in an initializer. Try replacing the reference to the instance member with a different expression

是否有另一种方法可以在不使 canvas 字段成为非最终字段的情况下做我想做的事情?

我知道我可以使用非最终私有字段和自定义 getter 使类“从外部”看起来相似,但这感觉像是一种不必要的解决方法。

【问题讨论】:

    标签: flutter dart dart-null-safety


    【解决方案1】:

    您可以使用工厂构造函数来调用您的真实(隐藏)构造函数,如下所示:

    class Foo {
      final PictureRecorder recorder;
      final Canvas canvas;
      final int margin;
    
      factory Foo({
        int margin = 10,
      }) {
        final recorder = PictureRecorder();
        final canvas = Canvas(recorder);
    
        return Foo._(
          recorder: recorder,
          canvas: canvas,
          margin: margin,
        );
      }
    
      Foo._({
        required this.recorder,
        required this.canvas,
        required this.margin,
      });
    }
    

    由于我们在工厂主体内运行时还没有创建任何对象,所以只要我们返回一个与工厂构造函数所属类型兼容的对象,我们就可以做任何事情。

    所以我们可以创建所有必要的值,然后将它们转发给我们真正的构造函数,并防止使用任何late 变量。

    【讨论】:

    • 我喜欢这种方法的一点是,我不会忘记初始化 canvas 而不会被编译器捕获。 late final 解决方案更简单,但理论上更容易出错。
    【解决方案2】:

    尝试对canvas 使用late 关键字。

    late final Canvas canvas;
    

    并且构造函数应该像这样更新:

    Foo({
        this.margin = 10,
      }) : recorder = PictureRecorder() {
        canvas = Canvas(recorder);
      }
    

    查看此帖子以获取更多信息:https://dev.to/pktintali/late-variables-in-dart-dart-learning-series-1-2opf

    【讨论】:

    • 为了完整起见:赋值也需要移动到构造函数的主体中,而不是在初始化列表中。
    • 我的错,我以为你已经知道了,我会更新
    • 我做到了,我只是想让以后阅读它的任何人都尽可能清楚地知道答案 - 感谢更新!
    • 你是对的!感谢您的反馈
    【解决方案3】:

    这是我想到的解决方法,但我宁愿不这样做:

    import 'dart:ui';
    
    class Foo {
      final PictureRecorder recorder;
      Canvas? _canvas;
      final int margin;
    
      Canvas get canvas => _canvas!;
    
      PatternVisualizer({
        this.margin = 10,
      }) : recorder = PictureRecorder() {
        _canvas = Canvas(recorder);
      }
    }
    

    【讨论】:

      【解决方案4】:

      你可以这样做

      class Foo {
        final PictureRecorder recorder;
        late final Canvas canvas;
        final int margin;
      
        Foo({
          this.margin = 10,
        }) : recorder = PictureRecorder() {
          canvas = Canvas(recorder);
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-29
        • 1970-01-01
        • 2019-07-12
        相关资源
        最近更新 更多