Scala匹配和引用相等性检查
根据变量类型,Scala有时匹配值,有时不匹配。 这个简单的程序说明了这个问题:Scala匹配和引用相等性检查,scala,Scala,根据变量类型,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-ma
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
检查。当变量的类型为notequaltowny
时,我们得到一个标准的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
)。有人能证实事实确实如此吗 有x.equals(x)
必须为真。如果你违反了合同,很多依赖于它的东西将不再起作用
编译器(例如集合库)必须假定对象“行为良好”。如果某个东西没有损坏,那么它就不是一个编译器错误
这样做的结果是,编译器可以在自己喜欢的时候优化某些东西。在本例中,当已知静态类型不需要时,可以跳过BoxesRunTime.equals
开销