为什么Scala没有类型安全等于方法?

bef*_*ore 15 scala equality equals

由于发明者强调了Scala的类型安全性,我不明白对象(至少从case类)缺少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)
Run Code Online (Sandbox Code Playgroud)

后来我需要多次检查位置并意外写入

  if (startPos == cubeOnStart) {
    // this code will never be executed, but unfortunately this compiles
  }
Run Code Online (Sandbox Code Playgroud)

但意思是

  if (startPos == cubeOnStart.pos) {
    // this code can be executed if positions are equal
  }
Run Code Online (Sandbox Code Playgroud)

如果一种方法===可用,我会用直觉来使用它.

是否有充分的理由或解释为什么缺少这种方法?

Tra*_*own 22

Scala中的平等是一个混乱,你的原因问题(Stack Overflow不是真正理想的场所)的答案是"因为语言设计者决定Java互操作性胜过在这种情况下做出合理的事情".

至少在Scala的最新版本中,您startPos == cubeOnStart将产生一个警告,指出比较这些不同类型的值"将始终产生错误".

Scalaz库提供了===你通过类型安全的寻找操作Equal类型的类.你会写这样的东西:

import scalaz._, Scalaz._

implicit val cubeEqual = Equal.equalA[Cube]
implicit val posEqual = Equal.equalA[Pos]
Run Code Online (Sandbox Code Playgroud)

现在startPos === cubeOnStart不会编译(这正是我们想要的),但startPos === cubeOnStart.pos将会,并将返回true.

  • 可以说,Java interop在一般情况下是合理的,因为它大大增加了可用库的大小和范围.这是实用语言的一个重要考虑因素...... (6认同)
  • 现在由Martin Odersky [考虑](http://www.scala-lang.org/blog/2016/05/06/multiversal-equality.html) (3认同)
  • 感谢您的解决方案。我知道对于 Java 互操作性,带有参数“Any”的 equals 方法是存在的,但是缺少类型安全变体似乎是语言/库中的一个很大的差距。 (2认同)