flutter - Dart是否会重用DateTime实例?

标签 flutter dart flutter-widget

我在摆弄GlobalObjectKey,我的对象是DateTime实例。我注意到,如果创建具有相同日期和时间的新实例,则会得到相同的实例“ID”:

DateTime newInstance = new DateTime.fromMicrosecondsSinceEpoch(datetime.microsecondsSinceEpoch);

我的调试打印说有两个具有相同ID的单独键:
[GlobalObjectKey DateTime#f056e] // Key assigned to Widget1
[GlobalObjectKey DateTime#f056e] // Key assigned to Widget2

但是,即使键似乎是重复的,我似乎也没有得到任何小部件/构建错误。

这是我正在做的更完整的示例:
class DateTimeKey{
  GlobalObjectKey key;
  DateTimeKey(DateTime datetime){
    DateTime newInstance = new DateTime.fromMicrosecondsSinceEpoch(datetime.microsecondsSinceEpoch);
    key = new GlobalObjectKey(newInstance);
  }
}

...

List<DateTimeKey> _bookingListMonthKeys = [];
List<DateTimeKey> _bookingListDayKeys = [];

DateTimeKey _monthKey = new DateTimeKey(theDate);
_bookingListMonthKeys.add(_monthKey);

DateTimeKey _dayKey = new DateTimeKey(theDate); // theDate here refers to the same DateTime instance as above
_bookingListDayKeys.add(_dayKey);

即使我遍历两个列表并像这样交叉引用它们
  _bookingListDayKeys.forEach((dayKey){
    _bookingListMonthKeys.forEach((monthKey){
      if( identical(dayKey, monthKey) )
        print('Identical DateTimeKeys found: $dayKey, $monthKey');

      if( identical(dayKey.key, monthKey.key) )
        print('Identical GlobalObjectKeys found: ${dayKey.key}, ${monthKey.key}');
    });
  });

它没有显示任何重复项,但是上面的打印输出显然具有相同的“id”(#f056e)。有人可以解释这是怎么回事吗?

最佳答案

所以我想我知道这里发生了什么。

首先,问题中的哈希数来自DateTime实例的hashCode属性。这用于== operator进行比较,因此对于表示同一时刻的两个DateTime实例来说将是相同的。

旁注:实际打印的字符串(#f056e)似乎是hashCode(即int)的十六进制表示形式的最后5个字符。

但是,hashCode不使用GlobalObjectKey。而是使用dart:core中的identityhashCode()方法:

Returns the identity hash code of object.

Returns the same value as object.hashCode if object has not overridden Object.hashCode. > Returns the value that Object.hashCode would return on this object, even if hashCode has > been overridden.

This hash code is compatible with identical.



从同一时间创建两个不同的DateTime实例时,它们的hashCode属性将相等,但identityHashCode()的结果将不同。因此,基本上,identityHashCode()似乎是我们将获得的对象的实际“内存地址”的最接近替代品。
DateTime instance1 = DateTime.now();
DateTime instance2 = DateTime.fromMicrosecondsSinceEpoch(instance1.microsecondsSinceEpoch);
print('hashCode: ${instance1.hashCode}, ${instance2.hashCode}   identityHashCode: ${identityHashCode(instance1)}, ${identityHashCode(instance2)}');

将导致:
I/flutter (23321): hashCode: 89064814, 89064814   identityHashCode: 383428552, 594747591

现在可以清楚地看到两个实例的hashCode相等,但是identityHashCode(DateTime)不同,这意味着它们实际上是单独的实例,但是在比较其hashCode属性或执行==操作时相等。

为什么打印GlobalObjectKey会打印其值的hashCode仍然是我无法理解的,这就是从一开始就让我失望的原因。

关于flutter - Dart是否会重用DateTime实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60205702/

相关文章:

flutter - 无法启动 Dart CLI 隔离(空)。在苹果电脑中

flutter - 将dart中的 map 更新为firestore

firebase - 写入 FireStore - 失败时如何显示错误(如果没有网络)

flutter - 如何删除 Expansion tile 的顶部和底部默认填充以导致小部件 flutter

flutter - 更新 Flutter 后 StaggeredGridView 不滚动

flutter - 如何本地化 BottomNavigationBarItem 标签

flutter - 使用InheritedWidget在子级中触发触发器 Action

Firebase Firestore 不显示由我的 flutter 应用程序创建的文档

ios - Flutter:如何在安装/卸载期间删除 FlutterSecureStorage 项目

flutter - 当用户在 Flutter 中提供错误数据时如何显示错误