Какой код генерируется для метода equals/hashCode класса case?

У меня есть некоторый Java-код, который я перевожу в Scala.

Код состоит из нескольких неизменяемых классов, которые бы соответствовали case class в Скале.

Но я не хочу вносить ошибки, поэтому хочу быть уверенным, что код, сгенерированный для equals а также hashCode является / ведет себя эквивалентно текущей реализации.

Я уже посмотрел в "Программирование в Scala", но это только говорит

В-третьих, компилятор добавляет "естественные" реализации методов toString, hashCode и equals для вашего класса.

1 ответ

Решение

Scala имеет опцию компилятора -Xprint:typer, который вы можете использовать, чтобы получить "исходный код пост-типирования, который он использует внутри".

scala -Xprint:typer -e 'case class Foo(a: String, b: Int)'

Здесь вы видите что-то вроде:

override def hashCode(): Int = ScalaRunTime.this._hashCode(Foo.this);
override def toString(): String = ScalaRunTime.this._toString(Foo.this);
override def equals(x$1: Any): Boolean = Foo.this.eq(x$1).||(x$1 match {
  case (a: String,b: Int)this.Foo((a$1 @ _), (b$1 @ _)) if a$1.==(a).&&(b$1.==(b)) => x$1.asInstanceOf[this.Foo].canEqual(Foo.this)
  case _ => false
});

Но это не говорит вам, как генерируется hashCode. Вот источник для этого:

def _hashCode(x: Product): Int = {
  var code = x.productPrefix.hashCode()
  val arr =  x.productArity
  var i = 0
  while (i < arr) {
    val elem = x.productElement(i)
    code = code * 41 + (if (elem == null) 0 else elem.hashCode())
    i += 1
  }
  code
}

И, в этом примере, первый случай сопоставления с шаблоном equals будет следующим:

case that: Foo => this.a == that.a && this.b == that.b
Другие вопросы по тегам