【问题标题】:Dart: Which is a better practice? Using 'late' or constructor initializer listDart:哪种做法更好?使用 'late' 或构造函数初始化列表
【发布时间】:2021-06-19 13:19:48
【问题描述】:

我正在为一个 Dart 类建模,考虑到新的 null 安全类型。我相信有两种有效的方法来初始化不可为空的属性,根据参数计算。

在本例中,我们将使用 Favorite 类。

该类在构造函数中使用初始化列表。

class Favourite {
  int favouriteId;

  Favourite({required this.favouriteId});

  Favourite.mapFromJson(dynamic json)
      : this.favouriteId = json["favouriteId"];
}

这个类使用'late'关键字。

class Favourite {
  late int favouriteId;

  Favourite({required this.favouriteId});

  Favourite.mapFromJson(dynamic json) {
    this.favouriteId = json["favouriteId"];
  }
}

您什么时候会使用其中一种?使用“迟到”感觉有风险。如果我添加了另一个命名构造函数,编译器就不会抱怨 'favouriteId' 没有被初始化。

还有其他选择吗?

谢谢!

【问题讨论】:

  • 据我所知,只有在确实需要时才应该使用late 关键字。所以构造函数初始化列表会是一个更好的选择。

标签: flutter dart dart-null-safety


【解决方案1】:

都没有。

使用初始化字段本身的默认构造函数和处理反序列化 json 对象的工厂构造函数:

class Favourite {
  final int favouriteId;

  Favourite({required this.favouriteId});

  factory Favourite.fromMap(Map<String, dynamic> map) {
    final favouriteId = json['favouriteId'];
    assert(favouriteId != null && favouriteId is int);
    
    return Favourite(
      favouriteId: favouriteId,
    );
  }
}

如果处理不当,late 关键字可能会令人头疼,因此一般情况下不要使用它,除非必须这样做。

【讨论】:

  • 我很高兴听到 'late' 关键字不是选项。代码感觉不是很健壮。我尝试了这个工厂示例,它可以工作,但我不明白为什么。为什么 Dart 现在对工厂很满意?它不再抱怨 'favouriteId' 没有被初始化。如果您有可以解释这一点的资料,我很乐意阅读!
  • 工厂方法本质上是一个静态方法,具有稍微更好的语法和一些属性,例如使用类的泛型和替换隐式构造函数。由于不需要这些,您可以轻松地将以上内容写为static Favourite mapFromJson(Map&lt;String, dynamic&gt; map) { ... }
  • @rmtmckenzie 我总是更喜欢工厂构造函数而不是静态“工厂”方法,如果没有其他原因,只是为了明确意图。此外,如果有必要,一个名为 fromMap 的工厂构造函数将使此类通过 json_serialization 包支持反序列化变得更加容易。
  • @Abion47 哦,绝对 - 抱歉我不清楚,这不是反对他们的论点,只是想澄清他们是什么。
【解决方案2】:

如果你确定 json 总是有一个“favouriteId”,你可以这样写:

class Favourite {
  int favouriteId;

  Favourite({required this.favouriteId});

  Favourite.mapFromJson(Map<String, dynamic?> json):
    assert(() {
      final favouriteId = json["favouriteId"];
      return favouriteId != null && favouriteId is int;
    }()),
    favouriteId = json["favouriteId"] as int;
}

void main() {
  
  dynamic m = {"favouriteId":2};
  final favourite = Favourite.mapFromJson(m);
  print("favourite id: ${favourite.favouriteId}");
  
}

【讨论】:

  • dynamic 标记为可为空是多余的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-14
  • 1970-01-01
  • 2011-01-26
相关资源
最近更新 更多