Соответствие Scala и проверка на равенство ссылок - PullRequest
2 голосов
/ 20 сентября 2019

В зависимости от типа переменной 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).Может ли кто-нибудь подтвердить, что это действительно так?

1 Ответ

5 голосов
/ 20 сентября 2019

Есть контракт на equals.x.equals(x) должно быть правдой.Если вы нарушите этот контракт, многие вещи, которые зависят от него, больше не будут работать.

Компилятор (и, например, библиотека коллекций) должен предполагать, что объекты "хорошо себя ведут".Это не ошибка компилятора, если что-то ломается, если они этого не делают.

В результате этого компилятор может оптимизировать некоторые вещи, когда ему это нравится.В данном случае издержки BoxesRunTime.equals можно пропустить, когда известно, что статический тип не нуждается в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...