Dart:为什么列表或地图分别不等于 [] 和 {}

Dart: why is a list or map not equal to [] and {} respectively

void main() {
  var a = [];
  var b = [];
  print(a == []);
  print(a == b);
  
  var c = ['c'];
  print(c == ['c']);
  
  var d = 'd';
  print(d == 'd');
}
false
false
false
true

这让我很困惑。为什么会这样?

编辑:我刚刚意识到它不一定是空的

它与 Dart 上的等式检查有关。他们不根据值来评估平等,而是使用 hashCodes.

如果您在 Flutter 上下文中使用 Dart,则可以使用原生 Flutter 方法 listEquals 使用列表进行基于值的比较。

如果你想要基于价值的平等 Objects 你必须 override == operator 或使用像 Equatable 这样的包来帮助你。

Dart 平台库通常选择不为可变集合(或一般的可变对象)提供本机 == 实现。

检查 [] == [] 似乎很明显,但它们是不同的对象。 如果你这样做:

var l1 = [];
var l2 = [];
print(l1 == l2);
l1.add("an element");
print(l1 == l2);

您希望这两个 == 给出相同的结果吗? 如果没有,怎么样:

var l1 = <int>[];
var l2 = <int>[];
var m = <List<int>>{l1}; // A set of lists.
print(m.contains(l2)); // true or false?
l1.add(1);
print(m.contains(l2)); // true or false?

除了其他语言也有的这些顾虑之外,Dart 还具体化了泛型。空 List<int> 和空 List<num> 不是同一个对象,运行时 type-checks 可以区分。 应该 <int>[] == <num>[] 那么?绝对说不最安全!

总而言之,Dart 没有== on List(或其他集合)递归检查两个列表是否包含相同(或相等)的元素。 它只说 true 如果它是 完全相同的对象 .

如果要检查 list-element-equality,可以使用 package:collection 中的 Equality 类,例如 ListEquality 和自定义 hash/equals 参数到散列 map/set 类。 示例:

const intListEquality = ListEquality<int>();
var listMap = LinkedHashMap<List<int>, String>(
    equals: intListEquality.equals, 
    hashCode: intListEquality.hash);
listMap[[1]] = "42";
print(listMap([1]); // 42