Получение информации о классе во время выполнения, когда вы не можете указать ClassTag

При написании тестов для проверки правильности выбора класса типов где-то внутри я столкнулся с стиранием типа. У меня нет возможности добавить ClassTag к сигнатуре, если только я не загрязню нетестовую версию трейта, потому что добавление : ClassTag изменяет сигнатуру метода так, что она больше не является переопределением, например:

trait Foo {
  def bar[T: MyTypeClass](t: T): Unit
}

class FooStubImpl extends Foo {
  override def bar[T: MyTypeClass: ClassTag](t: T): Unit = {
    val ct = classTag[T]
  }
}

Это вызывает следующую ошибку компиляции:

Ошибка: (12, 20) метод bar ничего не переопределяет. Примечание: суперклассы класса FooStubImpl содержат следующий не конечный член с именем bar:

override def bar[T](t: T)(implicit evidence$1: MyTypeClass[T]): Unit = {
         ^

Есть ли другой способ получить во время выполнения информацию о типе параметризованных типов, который не требует ClassTag?


person Arne Claassen    schedule 17.05.2015    source источник
comment
Разве вы не должны иметь возможность проверить, был ли выбран правильный класс типа, с помощью простой проверки на равенство? Я хотел бы увидеть вариант использования, в котором тест нарушается стиранием.   -  person Michael Zajac    schedule 18.05.2015
comment
Кстати, вы забыли extends Foo, хотя в данном случае это не меняет ошибку компилятора.   -  person 0__    schedule 18.05.2015
comment
@ m-z на самом деле вы правы, в случае с классами типов это не было проблемой, поскольку это неявные объекты, для которых я могу выполнять тесты на равенство. Я столкнулся с проблемой, когда не смог использовать класс типов, потому что он принимал пользовательские аргументы и создавал экземпляры разных параметризованных классов в операторе case. Я попытаюсь извлечь пример из фрагмента кода, который имеет смысл.   -  person Arne Claassen    schedule 18.05.2015


Ответы (1)


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

class FooStubImpl extends Foo {
  override def bar[T: MyTypeClass](t: T): Unit = {
    val clazz = t.getClass
  }
}
person 0__    schedule 18.05.2015
comment
Да, это работает. Спасибо. Возвращаясь к моему тестовому коду, чтобы выяснить, что у меня отличалось от того, что он жалуется на то, что мой тест на равенство был бесполезен из-за стирания типа. Я наверное что-то пропустил в переводе - person Arne Claassen; 18.05.2015