scala.Equals 特征中的 canEqual()

2024-04-27

从源代码来看scala/Equals.scala (here https://github.com/scala/scala/blob/2.11.x/src/library/scala/Equals.scala):

package scala
trait Equals extends scala.Any {
  def canEqual(that: scala.Any): scala.Boolean
  def equals(that: scala.Any): scala.Boolean
}

在文档中,它说:

应该从每个设计良好的 equals 方法中调用该方法,并且该方法可以在子类中重写。

我随机选择了一门延伸的课程scala.Equals这很简单易懂。我挑了scala.Tuple2[+T1, +T2],这扩展了特征scala.Product[T1, T2],这反过来又扩展了特征scala.Product,这反过来又扩展了特征scala.Equals.

不幸的是,似乎因为scala.Tuple2 is a 案例类, the canEqual() and equals()方法是自动生成的,因此在源代码中找不到scala/Tuple2.scala (here https://github.com/scala/scala/blob/2.11.x/src/library/scala/Tuple2.scala).

我的问题是:

  • 什么时候是扩展特质的好时机scala.Equals?
  • 应该怎样canEqual()得到实施?
  • 使用哪些最佳实践(或样板)canEqual() in equals()?

提前致谢!

PS:如果重要的话,我使用的是 Scala 2.11.7。


The canEquals方法用于覆盖期望equals应该是对称的 - 也就是说,如果(且仅当)a.equals(b)是真的,那么b.equals(a)也应该如此。当将类的实例与子类的实例进行比较时,可能会出现问题。例如。

class Animal(numLegs: Int, isCarnivore: Boolean) {
  def equals(other: Any) = other match {
    case that: Animal => 
      this.numLegs == that.numLegs && 
      this.isCarnivore == that.isCarnivore
    case _ => false
  }
}

class Dog(numLegs: Int, isCarnivore: Boolean, breed: String) extends Animal(numLegs, isCarnivore) {
  def equals(other: Any) = other match {
    case that: Dog => 
      this.numLegs == that.numLegs && 
      this.isCarnivore == that.isCarnivore &&
      this.breed == that.breed
    case _ => false
  }
}

val cecil = new Animal(4, true)
val bruce = new Dog(4, true, "Boxer")
cecil.equals(bruce) // true
bruce.equals(cecil) // false - cecil isn't a Dog!

要解决此问题,请确保两个实体具有相同(子)类型,使用canEqual在定义中equals:

class Animal(numLegs: Int, isCarnivore: Boolean) {
  def canEqual(other: Any) = other.isInstanceOf[Animal]
  def equals(other: Any) = other match {
    case that: Animal => 
      that.canEqual(this) &&
      this.numLegs == that.numLegs && 
      this.isCarnivore == that.isCarnivore
    case _ => false
  }
}

class Dog(numLegs: Int, isCarnivore: Boolean, breed: String) extends Animal(numLegs, isCarnivore) {
  def canEqual(other: Any) = other.isInstanceOf[Dog]
  def equals(other: Any) = other match {
    case that: Dog => 
      that.canEqual(this) &&
      this.numLegs == that.numLegs && 
      this.isCarnivore == that.isCarnivore &&
      this.breed == that.breed
    case _ => false
  }
}

val cecil = new Animal(4, true)
val bruce = new Dog(4, true, "Boxer")
cecil.equals(bruce) // false - call to bruce.canEqual(cecil) returns false
bruce.equals(cecil) // false
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

scala.Equals 特征中的 canEqual() 的相关文章

随机推荐