简体   繁体   English

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

[英]Difference between class constructor syntax in Dart

I have a class that I am creating that looks like this:我有一个我正在创建的类,如下所示:

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

I am getting a warning that says that "The final variables 'overview', 'posterPath', & '1' more must be initialized. There are also warnings around each variable saying 'title' can't be used as a setter because it is final.我收到一条警告说“必须初始化最终变量 'overview', 'posterPath', & '1' more 。每个变量周围也有警告说 'title' 不能用作 setter,因为它是最终的。

When I write the constructor using this syntax, the warnings go away:当我使用此语法编写构造函数时,警告消失:

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

What exactly is going on here?这里到底发生了什么?

Dart objects must be fully initialized before anyone gets a reference to the new object.在任何人获得对新对象的引用之前,必须完全初始化 Dart 对象。 Since the body of a constructor can access this , the object needs to be initialized before entering the constructor body.由于构造函数的主体可以访问this ,因此进入构造函数主体之前需要对对象进行初始化。

To do that, generative Dart constructors have an initializer list, looking similiar to C++, where you can initialize fields, including final fields, but you cannot access the object itself yet.要做到这一点,生成 Dart 构造函数有一个初始化列表,看起来类似于 C++,您可以在其中初始化字段,包括最终字段,但您还不能访问对象本身。 The syntax:语法:

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

uses an initializer list (the list of assignments after the : ) to initialize the final instance variables title , posterPath and overview .使用初始化列表( :之后的赋值列表)来初始化最终的实例变量titleposterPathoverview

The first constructor uses an "initializing formal" this.title to directly put the parameter into the field.第一个构造函数使用“初始化形式” this.title将参数直接放入字段中。

The constructor构造函数

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

is effectively a shorthand for:实际上是以下内容的简写:

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

Your constructor can combine all of these and a body:您的构造函数可以将所有这些和一个主体结合起来:

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

(A const constructor cannot have a body, but it can have an initializer list with some restrictions on the allowed expressions to ensure that they can be evaluated at compile-time). (const 构造函数不能有一个主体,但它可以有一个初始化列表,对允许的表达式有一些限制,以确保它们可以在编译时被评估)。

Dart separates properties initialization from the constructor body. Dart 将属性初始化与构造函数体分开。

A constructor has 3 parts :构造函数有 3 个部分:

  • the name/parameters definition名称/参数定义
  • properties initialization/super call/asserts属性初始化/超级调用/断言
  • A body, similar to a function immediately run on construction一个实体,类似于一个在构造时立即运行的函数

Both the initialization and body parts are optional.初始化和正文部分都是可选的。 final variables must be initialized on the first 2 parts. final变量必须在前两部分初始化。 They cannot be initialized inside the body.它们不能在体内初始化。

A full constructor will look like the following :完整的构造函数如下所示:

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

The main purpose of this initializer part is for body-less constructors which allows const constructors, a dart specific feature.这个初始化部分的主要目的是用于无体构造函数,它允许 const 构造函数,这是一个 dart 特定的特性。 See How does the const constructor actually work?请参阅const 构造函数实际上是如何工作的? for more details on these.有关这些的更多详细信息。

I just found some documentation around this, & it seams that the second version with the : is what's called the "initializer list" which allows you to initialize instance variables before the constructor body runs.我刚刚找到了一些关于此的文档,并且它认为第二个版本带有:是所谓的“初始化列表”,它允许您在构造函数主体运行之前初始化实例变量。

There is more detail around this in the documentation here . 此处的文档中有更多详细信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM