由于发明者突出显示 Scala 的类型安全性,我不明白对象(至少来自 case classes )缺少equals方法仅检查具有相同类型的对象的相等性。我希望方法===
默认情况下实现此行为。当然,Java互操作性必须有一个与Any
类型一起使用的方法,但在很多情况下我只想检查相同类型的对象之间的相等性。
例如,我有两个案例类并从中创建对象
case class Pos(x: Int, y: Int)
case class Cube(pos: Pos)
val startPos = new Pos(0, 0)
val cubeOnStart = new Cube(startPos)
以后我需要多次检查位置并意外写入
if (startPos == cubeOnStart) {
// this code will never be executed, but unfortunately this compiles
}
但意味着
if (startPos == cubeOnStart.pos) {
// this code can be executed if positions are equal
}
如果方法===
可用,我会直觉使用它。
是否有充分的理由或解释为何缺少这种方法?
答案 0 :(得分:22)
Scala中的平等是一团糟,而为什么问题(Stack Overflow不是真正理想的场所)的答案是“因为语言设计者决定Java互操作性胜过合理在这种情况下的事情“。
至少在Scala的最新版本中,您的startPos == cubeOnStart
会产生警告,指出比较这些不同类型的值“将始终产生错误”。
Scalaz library通过类型安全的===
类型类提供您正在寻找的Equal
运算符。你会写这样的东西:
import scalaz._, Scalaz._
implicit val cubeEqual = Equal.equalA[Cube]
implicit val posEqual = Equal.equalA[Pos]
现在startPos === cubeOnStart
无法编译(这正是我们想要的),但startPos === cubeOnStart.pos
会,并且会返回true
。
答案 1 :(得分:1)
截至2018年,Dotty有Multiversal Equality。但是,它需要开发人员定义相等检查才有意义的类型。总而言之,优雅的向后兼容解决方案。