Dart 立即分配给变量还是在构造函数中?

Ami*_*igo 3 dart flutter

在 Dart 中,立即赋值与在 Java 中的构造函数中是否有区别?

class Example {
    int x = 3;
}
Run Code Online (Sandbox Code Playgroud)

对比

class Example {
    int x;
    Example() {
        x = 3;
    }
}
Run Code Online (Sandbox Code Playgroud)

我问是因为当我使用 Flutter 并尝试将一个使用 setState 的函数分配给一个变量时,前一种方法是不可能的,但后一种方法是可能的。

jam*_*lin 12

在你的微不足道的情况下,没关系。

通常,您可以通过以下几种方式初始化实例变量:

内联(字段初始值设定项)

class Example1 {
  T x = value;
}
Run Code Online (Sandbox Code Playgroud)

好处:

  • 直接,简洁。
  • 成员将在所有构造函数中初始化。
  • 可用于初始化final或不可为空的成员。
  • Member 在调用基类构造函数之前被初始化,这在基类构造函数调用被派生类覆盖的成员函数时很重要。

缺点:

初始化列表

class Example2 {
  T x;

  Example2() : x = value;
}
Run Code Online (Sandbox Code Playgroud)

好处:

  • 可用于初始化final或不可为空的成员。
  • Member 在调用基类构造函数之前被初始化,这在基类构造函数调用被派生类覆盖的成员函数时很重要。
  • 可以利用构造参数。
  • 初始化的变量总是引用一个成员变量,而不是一个构造函数参数。

缺点:

  • 如果类有多个构造函数,则需要重复初始化,或者构造函数应重定向到公共构造函数。
  • 不能依赖,this因为初始化发生在this变得有效之前(即不能依赖其他实例成员)。
  • 只能初始化封闭类的成员。因为初始化列表是在调用基类构造函数之前执行的,所以它们不能设置基类成员。

构造函数体

class Example3 {
  T x;

  Example3() {
    x = value;
  } 
}
Run Code Online (Sandbox Code Playgroud)

好处:

  • 可以利用构造参数。
  • 可用于执行更复杂的初始化,例如无法通过单个表达式初始化成员的情况。
  • 可以使用this(即可以使用其他实例成员)。
  • 可用于设置基类成员。

缺点:

  • 不能用于初始化final或不可为空的成员。
  • 如果类有多个构造函数,则需要重复初始化或需要重构初始化代码(例如但不限于重定向到公共构造函数)。
  • 成员调用基类构造函数初始化。
  • 如果构造函数有一个隐藏成员变量的参数,很容易意外引用参数而不是成员。(有关详细信息,请参阅https://github.com/dart-lang/linter/issues/2552。)

我可能忘记了一些要点,但我认为这应该涵盖主要内容。

首先发生直接的内联初始化,然后是初始化列表,然后是构造函数体。另请参阅分配参数列表和初始化列表中的值之间的差异,这解释了为什么this仅在对象初始化的后期阶段才有效。