麻烦与父母'具有扩展多重特征的具体类(或案例类)的equals / hashCode中的字段(具体字段)

时间:2015-11-06 13:43:10

标签: scala equals hashcode traits case-class

我是Scala的新手并且对混合特征感到困惑。我使用多个特征来存储一些字段并将它们与具体类混合。

全局问题是关于equals和hashCode方法如何操作这些字段(traits中的字段可以具有默认值)。

实际上,我并没有计划拥有一堆协处理器并再次定义所有这些字段。我的班级可以有很多字段组合,我想使用Builder模式或简单的mutators链接。 我不明白如何在我的equals和具体类的hashCode中操作来自不同特征的字段(我只能用它们硬编码逻辑,但不能使用' super.equals()')。特征不能有自己的equals / hashCode方法,或者我在某些时候错了?

示例:

trait Task {  

  var name: Option[String] = None

  var comment: Option[String] = None

  ... // plenty other fields

}

trait Budget {

  var price: Option[Long] = None

}

class Event extends Task with Budget {

  var place: Option[String] = None

  ... // plenty other fields

}

当使用case类时 - 生成的equals / hashCode / toString不运行父字段(traits中的字段)

1 个答案:

答案 0 :(得分:3)

为什么不呢。 您可以轻松地override equalshashCode处理您喜欢的任何特征。

trait PP {
  override def hashCode(): Int = 1

  override def equals(obj: scala.Any): Boolean = true
}

class BB(val z: Int) extends PP {
  override def hashCode(): Int = super.hashCode()

  override def equals(obj: Any): Boolean = super.equals(obj) && (obj match {
    case b: BB => b.z == z
    case _ => false
  })
}

你应该非常小心hashCode并在这些特征中等于实现(同时进行类型检查:obj.isInstanceOf[otherTrait])以遵循这些方法的契约。

-

示例以证明所有equals都被调用。

scala> :paste
// Entering paste mode (ctrl-D to finish)

  trait T1 {
    override def equals(obj: scala.Any): Boolean = {
      println("T1 invoked")
      super.equals(obj)
    }
  }

  trait T2 {
    override def equals(obj: scala.Any): Boolean = {
      println("T2 invoked")
      super.equals(obj)
    }
  }
  trait T3 extends T1 {
    override def equals(obj: scala.Any): Boolean = {
      println("T3 invoked")
      super.equals(obj)
    }
  }
  class C1 extends T1 with T2 with T3 {
    override def equals(obj: scala.Any): Boolean = {
      println("C1 invoked")
      super.equals(obj)
    }
  }

  new C1().equals(new C1())

// Exiting paste mode, now interpreting.

C1 invoked
T3 invoked
T2 invoked
T1 invoked
defined trait T1
defined trait T2
defined trait T3
defined class C1
res7: Boolean = false

scala>

scala>