gpt4 book ai didi

scala - scala.Equals trait 中的 canEqual()

转载 作者:行者123 更新时间:2023-12-03 20:26:31 24 4
gpt4 key购买 nike

来自源码scala/Equals.scala ( here ):

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

在文档中,它说:

A method that should be called from every well-designed equals method that is open to be overridden in a subclass.



我随机选择了一个扩展 scala.Equals 的类这很容易理解。我选了 scala.Tuple2[+T1, +T2] ,它扩展了特征 scala.Product[T1, T2] ,这反过来又扩展了特征 scala.Product ,这反过来又扩展了特征 scala.Equals .

不幸的是,似乎是因为 scala.Tuple2是一个案例类, canEqual()equals()方法是自动生成的,因此在源代码中找不到 scala/Tuple2.scala ( here )。

我的问题是:
  • 什么时候是扩展特征的好时机 scala.Equals ?
  • 应该怎么做canEqual()被执行?
  • 使用的最佳实践(或样板)是什么 canEqual()equals() ?

  • 提前致谢!

    PS:如果有关系,我使用的是 Scala 2.11.7。

    最佳答案

    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

    关于scala - scala.Equals trait 中的 canEqual(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32093526/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com