Подтвердить что ты не робот

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 (включая, я думаю, пользовательские классы, о которых я даже не знаю)?

4b9b3361

Ответ 1

Исходная проблема не разрешима, и вот почему я рассуждаю:

Чтобы узнать, является ли тип экземпляром класса (например, Numeric), нам требуется неявное разрешение. Неявное разрешение выполняется во время компиляции, но нам нужно, чтобы это выполнялось во время выполнения. В настоящее время это невозможно, поскольку, насколько я могу судить, компилятор Scala не оставляет всю необходимую информацию в скомпилированном файле класса. Чтобы увидеть это, можно написать тестовый класс с помощью метода, который содержит локальную переменную, которая имеет неявный модификатор. Вывод компиляции не изменится при удалении модификатора.

Ответ 2

Используете ли вы DoubleWrapper для добавления методов в Double? Затем это должен быть прозрачный тип, т.е. Вы не должны хранить экземпляры, а скорее определяете сутенертные методы для возврата Double. Таким образом, вы можете продолжать использовать ==, как определено для примитивов, который уже делает то, что вы хотите (6.0 == 6 дает true).


Хорошо, так что если нет, как насчет

override def equals(o: Any): Boolean = o == value

Если вы построите методы equals других оболочек соответственно, вы должны в конечном итоге снова сравнить примитивные значения.

Другой вопрос: должен ли вы иметь такой метод equals для обертки с состоянием. Я не думаю, что изменяемые объекты должны быть равны в соответствии с одним из значений, которые они удерживают - вы, скорее всего, столкнетесь с проблемой.