【问题标题】:How exactly does the == operator work in dart when comparing objects?比较对象时 == 运算符在飞镖中究竟是如何工作的?
【发布时间】:2021-06-19 23:42:10
【问题描述】:

所以 Dart API 关于 == 操作符是这样说的:

相等运算符。

所有对象的默认行为是当且仅当 这个对象和其他对象是同一个对象。

重写此方法以在 a 上指定不同的相等关系 班级。覆盖方法必须仍然是等价关系。 也就是说,它必须是:

Total:它必须为所有参数返回一个布尔值。它永远不应该 扔。

自反:对于所有对象,o, o == o 必须是 true

对称:对于所有对象 o1o2o1 == o2o2 == o1 必须 要么都是true,要么都是false

传递:对于所有对象o1o2o3,如果o1 == o2o2 == o3true,那么o1 == o3 必须是true

方法也应该随着时间的推移保持一致,所以无论两个对象 只有当至少有一个对象是相等时才应该改变 修改。

如果子类覆盖了相等运算符,它应该覆盖 hashCode 方法也是为了保持一致性。

但是,如果 2 个对象相同,Dart 是如何检查的呢?

当且仅当返回true 这个对象和其他对象是同一个对象

可以理解为“检查两个对象是否引用同一个实例”,但显然不是这样。

假设我有 2 个实例

class Car {
  int tires = 4;
  Color color = Colors.blue;
  int doors = 4;
}

Car carA = Car();
Car carB = Car();

根据我的理解,如果我检查carA == carB,Dart 通过循环比较两个实例的所有属性?

如果是这样,如果某些属性是非基元类,它是否总是深入到基元?

谢谢

【问题讨论】:

  • "可以理解为“检查两个对象是否引用同一个实例”,但显然不是这样。" 你为什么认为不是?
  • 好问题。我猜我对运营商的理解从根本上是错误的。

标签: dart operators


【解决方案1】:

我相信 Dart 确实“检查两个对象是否引用同一个实例”。如果要比较属性,可以覆盖 == 运算符,例如:

class Car {
  int tires = 4;
  int doors = 4;

  @override
   bool operator ==(Object other) {
     return other is Car && this.tires == other.tires && this.doors == other.doors;
   } 
  @override
  int get hashCode => this.tires * this.doors;
}

void main() {
  Car carA = Car();
  Car carB = Car();
  print("equal ${carA==carB}");
  print("identical ${identical(carA,carB)}");
}

现在汽车是平等的。请注意,函数 identical() 确实会检查相同的对象。

Dart Spec 规定常量对象会检查属性,例如:

class ConstCar {
  final int tires = 4;
  final int doors = 4;
  const ConstCar();
}

void main() {
  ConstCar constCarA = const ConstCar();
  ConstCar constCarB = const ConstCar();
  print("equal ${constCarA==constCarB}");
  print("identical ${identical(constCarA,constCarB)}");
}

这对于 ==identical() 返回 true。

【讨论】:

  • 好吧,只是为了清楚。默认情况下,比较 (ObjectA == ObjectB) 与说 identical(ObjectA,ObjectB) 相同,因此如果它们是对同一实例的引用。如果我希望 == 运算符按属性比较对象,我必须重写运算符?
  • 是的,如果您想比较属性,您需要覆盖operator==(和hashCode)。
  • “Equatable”包可以帮助您完成大部分工作。
  • 调用==时并不是常量对象检查属性。相反,常量对象在创建时被规范化,因此如果您在两个位置创建属性为identical(不只是相等)的常量对象,其中一个被丢弃,编译器使用两个地方的相同对象(它将一个实例“规范化”为代表所有等效对象的实例)。
猜你喜欢
  • 2020-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-31
  • 1970-01-01
  • 1970-01-01
  • 2010-12-24
  • 2019-10-24
相关资源
最近更新 更多