Scala: проверка, является ли объект числовым
Возможно ли совпадение шаблона, если что-то есть Numeric
? Я хочу сделать следующее:
class DoubleWrapper(value: Double) {
override def equals(o: Any): Boolean = o match {
case o: Numeric => value == o.toDouble
case _ => false
}
override def hashCode(): Int = value ##
}
Но, конечно, это не работает, потому что Numeric
не является супертипом таких вещей, как Int
и Double
, это класс. Я также не могу сделать что-то вроде def equals[N: Numeric](o: N)
, потому что o
должен быть Any
, чтобы соответствовать контракту для equals
.
Итак, как мне это сделать без перечисления всех известных классов Numeric
(включая, я думаю, пользовательские классы, о которых я даже не знаю)?
Ответы
Ответ 1
Исходная проблема не разрешима, и вот почему я рассуждаю:
Чтобы узнать, является ли тип экземпляром класса (например, Numeric), нам требуется неявное разрешение. Неявное разрешение выполняется во время компиляции, но нам нужно, чтобы это выполнялось во время выполнения. В настоящее время это невозможно, поскольку, насколько я могу судить, компилятор Scala не оставляет всю необходимую информацию в скомпилированном файле класса. Чтобы увидеть это, можно написать тестовый класс с помощью метода, который содержит локальную переменную, которая имеет неявный модификатор. Вывод компиляции не изменится при удалении модификатора.
Ответ 2
Используете ли вы DoubleWrapper
для добавления методов в Double
? Затем это должен быть прозрачный тип, т.е. Вы не должны хранить экземпляры, а скорее определяете сутенертные методы для возврата Double
. Таким образом, вы можете продолжать использовать ==
, как определено для примитивов, который уже делает то, что вы хотите (6.0 == 6
дает true
).
Хорошо, так что если нет, как насчет
override def equals(o: Any): Boolean = o == value
Если вы построите методы equals
других оболочек соответственно, вы должны в конечном итоге снова сравнить примитивные значения.
Другой вопрос: должен ли вы иметь такой метод equals
для обертки с состоянием. Я не думаю, что изменяемые объекты должны быть равны в соответствии с одним из значений, которые они удерживают - вы, скорее всего, столкнетесь с проблемой.