List中的canEqual对Set参数返回true

Man*_*dha 0 scala

问题1 - 当我将List与Set(不同元素)进行比较时,为什么此代码返回true,但当我将List与List或Set of?进行比较时返回false?

scala> val l = List(1,2,3)
l: List[Int] = List(1, 2, 3)

scala> val l2=List(1,2,3)
l2: List[Int] = List(1, 2, 3)

scala> val l3=List(1,3,3)
l3: List[Int] = List(1, 3, 3)

scala> l.canEqual(l2)
res2: Boolean = true

/*I guess this returns true becuase canEqual check for type of the passed instance. Something like def canEqual(other: Any): Boolean = other.isInstanceOf[List] */

scala> l.canEqual(l3)
res3: Boolean = true

//but if canEqual checks for type of passed instance then why this returns true when I call canEqual on List but pass a Set

scala> val s = Set(1,2,3)
s: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> l.canEqual(s)
res4: Boolean = true

scala> val s2=Set(2,3,4)
s2: scala.collection.immutable.Set[Int] = Set(2, 3, 4)

scala> l.canEqual(s)
res5: Boolean = true

scala> l.canEqual(s2)
res6: Boolean = true
Run Code Online (Sandbox Code Playgroud)

列表中的canEqual可能不会检查实例List类型,但是某些超类实例或者可能不会覆盖equals.是这样的吗?

问题2 - 我读到canEquals与equals和hashcode一起使用来定义一个实例是否等于某个其他实例.canEquals通常由equals调用.当用户直接从代码调用canEqual时是否存在用例(就像我上面尝试的那样)?

dk1*_*k14 5

让我们从更简单的例子开始:

scala> "aaaa".canEqual(5)
res0: Boolean = true
Run Code Online (Sandbox Code Playgroud)

所以默认情况下一切都是平等的 - 但这并不意味着它会是.真正的用例canEqual是禁用等价(参见本文):

非最终类的canEqual方法.如果子类不希望等于父类或兄弟类,则允许子类覆盖canEqual.

所以完整的原因canEqual是继承(在兄弟姐妹/父母中严格禁用平等).不建议在外面使用它,equals因为它违反了上面文章中所述的Liskov替代原则.

恕我直言,我不建议使用它,这是违反直觉和危险的.如果你需要禁用实体之间的相等性,最好更喜欢组合继承,因为继承在逻辑上需要继承相等,但组合更灵活.