I tried to override the equals method of java.lang.Object by doing this:
extension(cellTower: CellTower)
// CellTower class unfortunately has no equals() implementation,
// but a toString(), so we use this for equality
def equals(other: Object): Boolean = cellTower.toString == other.toString
It didn't get used for equality (==).
Is this impossible with Scala 3 extension methods or am I doing something wrong?
CodePudding user response:
This is not possible: Object
already has the method equals
, all reference types extend Object
, so the compiler will always take the overridden java.lang.Object.equals
, and never look for any extension methods.
A more complete version of your example would look a little bit like this:
case class Foo(a: Int, b: String):
override def toString = b
extension (foo: Foo)
def equals(other: AnyRef): Boolean = foo.toString == other.toString
val u = Foo(42, "x")
val v = Foo(58, "x")
println(u.toString == v.toString) // true
println(u == v) // false
What you could do however, is to use your own implementation of Eq
with ===
:
import cats.kernel.Eq
import cats.syntax.eq._
case class Foo(a: Int, b: String):
override def toString = b
object Foo:
given Eq[Foo] with
def eqv(x: Foo, y: Foo): Boolean = x.b == y.b
val u = Foo(42, "x")
val v = Foo(58, "x")
println(u.toString == v.toString) // true
println(u == v) // false
println(u === v) // true
Same applies to toString
-> Show
and hashCode
-> Hash
(link to scaladoc for cats.kernel.Hash
). Whenever you need more control over equality / hashing / string-representation, consider using the corresponding type classes instead.