为案例类的 equals/hashCode 方法生成什么代码?

发布于 2024-10-09 13:01:33 字数 293 浏览 1 评论 0原文

我有一些 Java 代码,我正在将其转换为 Scala。

该代码由一些不可变的类组成,这些类适合 Scala 中 case 类 的用途。

但我不想引入错误,因此我想确保为 equalshashCode 生成的代码与当前实现等效。

我已经看过“Scala 编程”,但它只说

第三,编译器添加了 toString 方法的“自然”实现, hashCode,等于你的类。

I have some Java code which I'm translating to Scala.

The code consists of some immutable classes which would fit the purpose of a case class in Scala.

But I don't want to introduce bugs, therefore I want to be sure that the code being generated for equals and hashCode is/behaves equivalent to the current implementation.

I already looked in "Programming in Scala" but it only says

Third, the compiler adds “natural” implementations of methods toString,
hashCode, and equals to your class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈甜 2024-10-16 13:01:33

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

Scala has a compiler option -Xprint:typer, which you can use to get the "post-typing source code that it uses internally".

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

Here you see something like:

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
});

But, this doesn't tell you how hashCode is generated. Here's the source for that:

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
}

And, in this example, the first case of the equals pattern matching would just be:

case that: Foo => this.a == that.a && this.b == that.b
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文