Почему метод Scala не имеет типа безопасный эквивалент?
Поскольку изобретатели подчеркивают Scala тип безопасности, я не понимаю отсутствие метода equals на объектах (по крайней мере, из классов case), что позволяет проверять равенство только на объектах одного типа. Я бы хотел, чтобы метод ===
реализовал это поведение по умолчанию. Разумеется, необходимо, чтобы Java-совместимость имела метод, который работает с типом Any
, но во многих случаях я хочу проверить только равенство между объектами того же типа.
Зачем мне это нужно?
Например, у меня есть два класса case и создаю из него объекты
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
}
Если бы был доступен метод ===
, я бы использовал его по интуиции.
Есть ли веская причина или объяснение, почему такой метод отсутствует?
Ответы
Ответ 1
Равенство в Scala является беспорядком, и ответ на ваш вопрос о том, почему этот вопрос (в котором Qaru не является идеальным местом для проведения), "потому что разработчики языка решили, что совместимость с Java сопряжена с разумными соображениями в этом случае".
По крайней мере, в последних версиях Scala ваш startPos == cubeOnStart
приведет к предупреждению о том, что сравнение значений этих разных типов всегда будет давать false.
Библиотека Scalaz предоставляет оператор ===
, который вы ищете, с помощью типа типа Equal
. Вы должны написать что-то вроде этого:
import scalaz._, Scalaz._
implicit val cubeEqual = Equal.equalA[Cube]
implicit val posEqual = Equal.equalA[Pos]
Теперь startPos === cubeOnStart
не будет компилироваться (это именно то, что мы хотим), но startPos === cubeOnStart.pos
будет и вернет true
.