В зависимости от типа переменной Scala иногда совпадает со значением, а иногда нет.Проблема иллюстрируется этой простой программой:
class NotEqualToAnything {
override def equals(obj: Any): Boolean = false
}
val x = new NotEqualToAnything()
x match {
case `x` =>
println("WTF x equal to itself")
case _ =>
println("no-match") // This got printed
}
val y: AnyRef = new NotEqualToAnything()
y match {
case `y` =>
println("WTF y equal to itself") // This got printed
case _ =>
println("no-match")
Когда переменная имеет тип AnyRef
, сгенерированный код содержит вызов BoxesRunTime.equals
, который действительно проверяет y == y
перед вызовом y.equals(y)
,Когда тип переменной NotEqualToAnything
, мы дважды получаем стандартную x == null
проверку, а затем вызов x.equals(x)
.
Я проверял это на
Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_201).
Интересноесли это ошибка компилятора и о ней нужно сообщить, если это «желаемое» поведение.На мой взгляд, оба случая должны вести себя одинаково.
Одна из гипотез состоит в том, что компилятор ожидает, что классы будут следовать контракту при переопределении equals
, и поэтому ожидает, что equals
будет отражающим (x.equals(x) == true
).Может ли кто-нибудь подтвердить, что это действительно так?