在DART中初始化成员变量的方式是否有所不同? [英] Is there a difference in how member variables are initialized in Dart?
本文介绍了在DART中初始化成员变量的方式是否有所不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在DART中,立即赋值与像Java一样在构造函数中赋值有区别吗?
class Example {
int x = 3;
}
vs
class Example {
int x;
Example() {
x = 3;
}
}
我之所以这样问,是因为当我使用Ffltter并尝试将使用setState的函数赋值给变量时,使用前一种方法是不可能的,但使用后一种方法是可能的。
推荐答案
在您的琐碎案例中,这无关紧要。
一般来说,您可以通过以下几种方式初始化实例变量:
内联(字段初始值设定项)
class Example1 {
T x = value;
}
优势:
- 直接、简洁。
- 成员将在所有构造函数中初始化。
- 可用于初始化
final
或不可为空的成员。 - 成员在调用基类构造函数之前初始化,这在基类构造函数调用被派生类重写的成员函数时很重要。
缺点:
- 不能依赖构造参数。
- 通常不能依赖
this
,因为初始化发生在this
生效之前(即不能依赖其他实例成员)。(An exception is if the member is initialized lazily by declaring itlate
。这需要启用空安全功能。)
初始化式列表
class Example2 {
T x;
Example2() : x = value;
}
优势:
- 可用于初始化
final
或不可为空的成员。 - 成员在调用基类构造函数之前初始化,这在基类构造函数调用被派生类重写的成员函数时很重要。
- 可以利用构造参数。
- 初始化变量始终引用成员变量,而不是构造函数参数。
缺点:
- 如果该类有多个构造函数,则需要复制初始化,或者构造函数应重定向到公共构造函数。
- 不能依赖
this
,因为初始化发生在this
生效之前(即不能依赖于其他实例成员)。 - 只能初始化封闭类的成员。由于初始值设定项列表是在调用基类构造函数之前执行的,因此它们无法设置基类成员。
构造函数主体
class Example3 {
T x;
Example3() {
x = value;
}
}
优势:
- 可以利用构造参数。
- 可用于执行更复杂的初始化,例如无法通过单个表达式初始化成员的情况。
- 可以使用
this
(即可以使用其他实例成员)。 - 可用于设置基类成员。
缺点:
- 不能用于初始化
final
或不可为空的成员。 - 如果类有多个构造函数,则需要复制初始化,或者需要重构初始化代码(例如但不限于重定向到公共构造函数)。
- 成员在调用基类构造函数之后初始化。
- 如果构造函数有一个隐藏成员变量的参数,则很容易意外引用该参数而不是该成员。(详情请参见https://github.com/dart-lang/linter/issues/2552。)
我可能忘记了一些要点,但我认为这应该涵盖了主要的要点。
首先进行直接内联初始化,然后是初始化列表,然后是构造函数体。另请参阅Difference between assigning the values in parameter list and initialiser list,它解释了为什么this
仅对对象初始化的后期阶段有效。
举个例子,成员在哪里初始化很重要:
class Base {
Base() {
doSomething();
}
void doSomething() {}
}
class DerivedEarly extends Base {
int? x;
DerivedEarly() : x = 42;
@override
void doSomething() => print(x);
}
class DerivedLate extends Base {
int? x;
DerivedLate() {
x = 42;
}
@override
void doSomething() => print(x);
}
void main() {
DerivedEarly(); // Prints: 42
DerivedLate(); // Prints: null
}
这篇关于在DART中初始化成员变量的方式是否有所不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文