首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala匹配和引用相等性检查

Scala匹配和引用相等性检查
EN

Stack Overflow用户
提问于 2019-09-20 17:34:43
回答 1查看 161关注 0票数 2

根据变量类型的不同,Scala有时匹配值,有时不匹配。这个简单的程序演示了这个问题:

代码语言:javascript
复制
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.equals(y)之前确实会执行y == y检查。当变量的类型为NotEqualToAnything时,我们得到一个标准的x == null检查两次,然后调用x.equals(x)

我对此进行了测试

代码语言:javascript
复制
Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_201).

我想知道这是否是编译器错误,应该报告这是否是“期望的”行为。在我看来,这两种情况的行为应该是相同的。

一种假设是编译器期望类在覆盖equals时遵循约定,因此期望equals是反射的(x.equals(x) == true)。有人能证实这是真的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-20 17:56:21

这就是a contract for equalsx.equals(x)必须是真的。如果你破坏了合同,许多依赖它的东西将不再起作用。

编译器(例如集合库)必须假定对象是“行为良好的”。如果某些东西没有发生故障,那么它就不是编译器错误。

这样做的结果是,编译器可以在感觉上优化一些东西。在目前的情况下,当知道静态类型不需要BoxesRunTime.equals开销时,可以跳过该开销。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58025695

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档