Dart 中类构造函数语法之间的差异



我正在创建一个看起来像这样的类:

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'];

这到底是怎么回事?

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

为此,生成 Dart 构造函数有一个初始值设定项列表,类似于 C++,您可以在其中初始化字段(包括最终字段(,但还无法访问对象本身。语法:

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 构造函数不能有主体,但它可以有一个初始值设定项列表,对允许的表达式有一些限制,以确保它们可以在编译时计算(。

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

构造函数有 3 个部分:

  • 名称/参数定义
  • 属性初始化/超级调用/断言
  • 一个主体,类似于在构造上立即运行的函数

初始化和正文部分都是可选的。final变量必须在前 2 个部分初始化。它们不能在正文内部初始化。

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

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

此初始值设定项部分的主要用途是用于无主体构造函数,它允许 const 构造函数,这是 dart 特定的功能。请参阅常量构造函数实际如何工作?有关这些的更多详细信息。

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

此处的文档中有更多详细信息。

最新更新