Will the var members in case class affect case class's equality?

半世苍凉 提交于 2019-12-04 04:11:22

Case class equality is based solely on its primary constructor attributes, whether they're var or val (yes, you can make them var by giving an explicit var to override the implied val that case class constructor args possess.) Adding properties in the body of a case class does not influence the compiler-generated equals(other: Any) method.

Witness:

package rrs.scribble

object  CCVarEq
{
  case class CC1(i: Int, j: Float, var k: Double)

  case class CC2(i: Int, j: Float, var k: Double) {
    var l = math.Pi
  }

  def show {
    val cc11 = CC1(1, 2.0f, 3.0)
    val cc12 = CC1(1, 2.0f, 3.0)

    val cc21 = CC2(1, 2.0f, 3.0); cc21.l = math.E
    val cc22 = CC2(1, 2.0f, 3.0)

    printf("cc11 == cc12: %s%n", cc11 == cc12); cc12.k = math.Pi * math.E
    printf("cc11 == cc12: %s%n", cc11 == cc12)

    printf("cc21 == cc22: %s%n", cc21 == cc22)
  }
}

In the REPL:

scala> import rrs.scribble.CCVarEq._
import rrs.scribble.CCVarEq._

scala> show
cc11 == cc12: true
cc11 == cc12: false
cc21 == cc22: true

And all jamie's points about concurrency are valid, too.

It's not that simple. You update a case class var on one thread, and another thread is performing an equality check. Unless the var is volatile, it's plausible that the change to the var won't be propagated to the other thread before the equality check is performed. So you could have race conditions. Regardless if this happens only once or many times.

Is the value to be changed once undefined up to that point? If so, use a lazy val. It has a synchronization concern that could slow high-performance code, but would otherwise meet your use case.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!