I am studying Scala and ran into the following puzzle.
I can define the following case classes:
abstract class Expr
case class Number(n: Int) extends Expr
When I create two instances from the class Number
and compare them
val x1 = Number(1)
val x2 = Number(1)
x1 == x2
I have the following result:
x1: Number = Number(1)
x2: Number = Number(1)
res0: Boolean = true
So x1
and x2
are the same.
However, if I drop the case
modifier in the Number
class definition, i.e.
abstract class Expr
class Number(n: Int) extends Expr
and then compare two instances from the Number
class in the same way
val x1 = new Number(1)
val x2 = new Number(1)
x1 == x2
I have the following output:
x1: Number = Number@1175e2db
x2: Number = Number@61064425
res0: Boolean = false
It says that this time x1
and x2
are different.
Could you tell me why is this? What difference does case
make in terms of comparing two instances?
Thanks, Pan
When you define a case class in Scala, the compiler generates an equals
method which checks for deep equality (i.e., the contents of the class).
From: http://www.scala-lang.org/old/node/107
For every case class the Scala compiler generates equals method which implements structural equality and a toString method.
When you drop the case
keyword, you generate regular classes, and doing an ==
on them checks for reference (shallow) equality. Since you're comparing two unique instances of the class, they fail reference equality even though their contents are the same.
For difference between shallow and deep equality, see:
What is the difference between being shallowly and deeply equal? How is this applied to caching?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With