Dart - 初始化相互依赖的 final class 成员

Dart - initializing final class members depedent on each other

我喜欢在我的 classes 中使用 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 让 class 看起来“从外面”看起来很相似,但感觉这是一个不必要的解决方法。

尝试对 canvas 使用 late 关键字。

late final Canvas canvas;

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

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

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

你可以做到

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

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

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

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);
  }
}

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

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,
  });
}

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

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