Dart 类构造函数初始化构造函数体中的字段

时间:2021-04-27 15:35:07

标签: class dart constructor

我正在尝试初始化以下代码中的现场任务,但出现错误:Non-nullable instance field 'tasks' must be initialized.。我可以使用 Example(this.tasks) {}Example(String json) : this.tasks = [json] 之类的语法成功初始化字段,但是当我需要使用多行来计算如下代码中的值时,我不确定如何初始化字段。

import 'dart:convert';

class Example {
  List<String> tasks;
  Example(String json) {
    List<String> data = jsonDecode(json);
    this.tasks = data;
  }
}

3 个答案:

答案 0 :(得分:2)

在本例中,您不需要多行来计算值。你可以这样做:

Example(String json) : this.tasks = jsonDecode(json);

在您确实需要多个语句的更一般情况下,如果字段初始化值不相关,我会为每个使用辅助函数:

Example(String json) : this.tasks = _computeTasks(json);
static List<String> _computeTasks(String json) {
  List<String> result;
  // compute compute compute
  return result;
}

如果您有多个字段需要使用来自同一计算的值进行初始化,我会首先尝试将其设为工厂构造函数:

  final Something somethingElse;
  Example._(this.tasks, this.somethingElse);
  factory Example(String json) {
    List<String> tasks;
    Something somethingElse;
    // compute compute compute
    return Example._(tasks, somethingElse);
  }

如果构造函数需要生成,并且你需要在同一个计算中计算多个值,并且不改变这一点非常重要,那么我会可能制作一个包含这些值的中间对象:

  Example(String json) : this._(_computeValues(json));
  Example._(_Intermediate values) 
      : tasks = values.tasks, somethingElse = values.somethingElse;
  static _Intermediate _computeValues(String json) {
    List<String> tasks;
    Something somethingElse;
    // compute compute compute
    return _Intermediate(tasks, somethingElse);
  }
  ...
}

// Helper class.
class _Intermediate {
  final List<String> tasks;
  final Something somethingElse;
  _Intermediate(this.tasks, this.somethingElse);
}

如果类型相同,您或许可以使用 List 代替中间值的辅助类。或者,您可以重用像

这样的类
class Pair<S, T> { 
  final S first; 
  final T second; 
  Pair(this.first, this.second);
}

你怎么做并不重要,用户永远不会看到中间值。

答案 1 :(得分:1)

您是对的,非空值必须首先在对象构造时作为参数或在初始化列表中进行初始化。

然而,您不能在初始化完成之前调用对象上的方法。 (而且您可能无论如何都不应该这样做,因为对象构造应尽可能保持轻量级)

如果在构造对象之前(或之后)需要进行任何处理,则可以使用 factory 构造函数。事实上,您似乎正在尝试从 json 创建一个对象,这正是 official docs 中示例的内容。

为了简化我链接到的那个例子并删除任何关于缓存的内容,它看起来像这样:

class Logger {
  String name;
  bool mute = false;

  factory Logger.fromJson(Map<String, Object> json) {
    return Logger._internal(json['name'].toString());
  }

  Logger._internal(this.name);

}

答案 2 :(得分:0)

Irn 的解决方案很好。你也可以使 tasks 可以为空,如果你没问题的话:

  List<String>? tasks;
相关问题