I have made heavy use of case classes in my code, replying on the underlying equality definitions of case class to behave correctly. Then now I found that I need to add another field member to a case class.
- So if I add a
var
field member in case class, will it mess up the equality attributes for the case class? - If 1 is yes, then what if I just change the
var
field value once, after that, no any reassignment will happen, before the case class goes into any collections or do equality comparison, will that still mess up the equality behaviors?
Case class equality is based solely on its primary constructor attributes, whether they're
var
orval
(yes, you can make themvar
by giving an explicitvar
to override the impliedval
that case class constructor args possess.) Adding properties in the body of acase class
does not influence the compiler-generatedequals(other: Any)
method.Witness:
In the REPL:
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.