繁体   English   中英

在 Dart 类构造函数中使用可选命名参数的正确方法

[英]Right way of using optional named parameters in Dart class constructor

飞镖菜鸟在这里。 我定义了一个类如下:

class Balance{
  String ccy;
  late Money receivable;
  late Money payable;
  Balance(this.ccy, {Money? receivable, Money? payable}){
   this.receivable = receivable??Money.from(0, code:ccy);
   this.payable = payable??Money.from(0, code:ccy);
  };
}

我把它定义为上面的原因是:

  1. 我希望应付款和应收款字段永远不会为空,但同时,我不想在创建 Balance 对象时总是为这些字段传递值。
  2. 我希望需要 ccy 参数并使用该参数将应付账款和应收账款字段初始化为 0。

这是定义 Balance 类的正确方法吗? 有没有更好的办法?

编写此代码的惯用方法是:

class Balance{
  final String currency;
  final Money receivable;
  final Money payable;
  Balance(this.currency, {Money? receivable, Money? payable}) 
      : receivable = receivable ?? Money.from(0, code: currency),
        payable = payable ?? Money.from(0, code: currency);
}

(加上文档!)

通过初始化初始化列表中的字段(正是因为这个原因而存在),您可以使字段最终且不可为空,并且仍然使用依赖参数的计算来初始化它们。

我永远不会在公共领域使用late 在这种情况下,您实际上会在构造函数中立即对其进行初始化,因此不存在类的客户端在初始化之前意外读取该字段的风险。 他们只是不知道,他们所看到的只是领域late 即使您将字段final ,没有初始化程序的late final字段仍将在公共 API 中具有可见的 setter。

如果您确实希望字段是可变的,那么您可以删除final . 那么late也没有那么糟糕,只要您仍然确保在其他人看到该对象之前已初始化这些字段。 那么你通常还是按照我在这里做的事情来代替,避免late

您可能需要late的一种情况是您需要创建最终字段的循环结构。 就像是

class MainNode {
  final String name;
  late final SubNode _sub;
  MainNode(this.name, String data) {
    _sub = SubNode(this, data);
  }
  SubNode get sub => _sub; 
}
class SubNode {
  final MainNode parent;
  String data;
  SubNode(this.parent, this.data);
}

对于这样的事情,您需要访问this创建子节点, late final字段是有意义的,并确保_sub实际上只写入一次。 (不过,我通过将其_sub私有来避免在 API 中暴露_sub setter。)

暂无
暂无

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

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