飞镖构造函数后的冒号

Posted

技术标签:

【中文标题】飞镖构造函数后的冒号【英文标题】:Colon after Constructor in dart 【发布时间】:2018-10-20 19:48:13 【问题描述】:

此代码来自颤振画廊,我正在尝试理解和调整它。我会知道这个语法是什么意思:

class DemoItem<T> 
  DemoItem(
    this.valueName,
    this.hintName,
    this.valueSurname,
    this.hintSurname,
    this.builder,
    this.valueToString

  ) : textController = new TextEditingController(text: valueToString(valueName));

特别是我会知道构造函数后面的冒号是什么意思,以及是否有一种方法可以定义另一个 TextEditingController,除了已经定义的那个。

【问题讨论】:

【参考方案1】:

:之后的部分称为“初始化列表”。它是一个,分隔的表达式列表,可以访问构造函数参数,可以赋值给实例字段,甚至是final实例字段。这很方便初始化具有计算值的最终字段。

初始化列表也用于调用其他构造函数,如: ..., super('foo')

从 Dart 1.24 版开始,初始化列表也支持assert(...),方便检查参数值。

初始化列表无法从this读取,因为超级构造函数需要在访问this有效之前完成,但它可以分配给this.xxx

如用户693336在cmets中提到的那样指出:

这也意味着初始化列表在构造函数主体之前执行。此外,所有超类的初始化列表都会在任何构造函数主体执行之前执行。

示例(复制自https://github.com/dart-lang/language/issues/1394):

class C 
  final int x;
  final int y;
  C(this.x) : y = x + 1;

【讨论】:

您的回答非常清晰、完整且详尽。我明白了并解决了我的问题。谢谢! 很高兴听到:) @lrn 很高兴知道像 this.foo 这样的参数现在也可以在初始化列表中访问。 这与为构造函数提供主体并在那里初始化变量有何不同? 这个答案是正确的,但我觉得可以通过明确指出初始化程序在构造函数主体之前运行来改进它。当前答案中暗示了这一点,但值得说明。这允许在执行构造函数主体之前计算或初始化某些字段。【参考方案2】:

为了详细说明其他答案并完成语法,还可以为构造函数提供一个实体以及初始化代码

NonNegativePoint(this.x, this.y) : assert(x >= 0), assert(y >= 0) 
    print('I just made a NonNegativePoint: ($x, $y)');

^ 这里的断言发生在主体执行之前

另一个用例是在正文执行之前为最终字段分配值

final num x;
final num y;

Point.fromJson(Map<String, num> json) : x = json['x'], y = json['y'] 
    print('In Point.fromJson(): ($x, $y)'); 

【讨论】:

如果在初始化列表中断言失败,会停止构造函数的执行吗? 谢谢——当我发现这个问题时,我正在寻找如何使用构造函数主体与冒号:构造函数代码。

以上是关于飞镖构造函数后的冒号的主要内容,如果未能解决你的问题,请参考以下文章

飞镖中的构造函数[重复]

冒号初始化与构造函数内赋值

C++ 构造函数后面有冒号 ~ : ()

C++类成员冒号初始化以及构造函数内赋值

C++成员初始化列表(构造函数后加冒号:)(用于在构造函数中初始化类成员变量,可以避免使用构造函数体内的赋值语句,可以确保成员变量在对象构造之初就已经被正确初始化,提高代码的性能和可读性)

您可以将命名参数与简写构造函数参数结合起来吗?