Dart中的类构造函数语法之间的区别

时间:2018-09-27 03:06:34

标签: dart flutter

我正在创建一个类,如下所示:

class Movie {
  final String title, posterPath, overview;

  Movie(this.title, this.posterPath, this.overview);

  Movie.fromJson(Map json) {
    title = json["title"];
    posterPath = json["poster_path"];
    overview = json['overview';
  }
}

我收到一条警告,指出“必须初始化最终变量'overview','posterPath'和'1'。每个变量周围也有警告说'title'不能用作二传手,因为它是最终的。

当我使用这种语法编写构造函数时,警告消失了:

Movie.fromJson(Map json)
   : title = json["title"],
     posterPath = json["poster_path"],
     overview = json['overview'];

这到底是怎么回事?

3 个答案:

答案 0 :(得分:4)

在任何人获得对新对象的引用之前,必须完全初始化Dart对象。由于构造函数的主体可以访问this,因此需要在进入构造函数主体之前 初始化对象。

要做到这一点,生成式Dart构造函数具有一个初始化程序列表,看起来类似于C ++,您可以在其中初始化字段(包括final字段),但是您尚不能访问对象本身。语法:

Movie.fromJson(Map json)
    : title = json["title"],
      posterPath = json["poster_path"],
      overview = json['overview'];

使用初始化程序列表(在:之后的赋值列表)来初始化最终实例变量titleposterPathoverview

第一个构造函数使用“初始化形式” this.title直接将参数放入字段。

构造函数

Movie(this.title, this.posterPath, this.overview);

实际上是以下内容的缩写:

Movie(String title, String posterPath, String overview)
    : this.title = title, this.posterPath = posterPath, this.overview = overview;

您的构造函数可以将所有这些和一个主体结合在一起:

Movie(this.title, this.posterPath, String overview)
   : this.overview = overview ?? "Default Overview!" {
  if (title == null) throw ArgumentError.notNull("title");
}

(const构造函数不能具有主体,但是它可以具有一个初始化器列表,对允许的表达式有一些限制,以确保可以在编译时对其进行求值。)

答案 1 :(得分:3)

Dart将属性初始化与构造函数主体分开。

构造函数分为三部分:

  • 名称/参数定义
  • 属性初始化/超级调用/声明
  • 类似于功能的主体可以立即在构造上运行

初始化和主体部分都是可选的。 final变量必须在前2个部分中初始化。它们无法在体内初始化。

完整的构造函数如下所示:

MyClass(int value)
    : assert(value > 0),
      property = value, 
      super();
{
  print("Hello World");
} 

此初始值设定项部分的主要目的是用于无主体的构造函数,该函数允许const构造函数(dart特定功能)。有关这些的更多详细信息,请参见How does the const constructor actually work?

答案 2 :(得分:0)

我刚刚找到了一些有关此问题的文档,并且它表明带有:的第二个版本是所谓的“初始化列表”,它允许您在构造函数体运行之前初始化实例变量。

here文档中对此有更详细的说明。