1

我在摆弄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)。有人可以解释这里发生了什么吗?

4

1 回答 1

0

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

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

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

但是,hashCode不被GlobalObjectKey. 相反,它使用来自以下的方法identityhashCode()dart:core

返回对象的身份哈希码。

如果 object 没有覆盖 Object.hashCode,则返回与 object.hashCode 相同的值。> 返回 Object.hashCode 将在此对象上返回的值,即使 hashCode 已 > 被覆盖。

此哈希码与相同的兼容。

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属性或执行==操作时相等。

为什么打印 aGlobalObjectKey会打印hashCode它的价值仍然超出我的能力范围,这就是让我从一开始就失望的原因。

于 2020-02-13T14:32:10.650 回答