Отслеживать тип времени выполнения параметра типа через TypeTag при использовании с типом Existential в Scala
я имеюtrait
с параметром типа. Чтобы получить тип времени выполнения я используюTypeTag
, Однако когда этоtrait
(и его классы) используются сexistential type
в коллекции, напримерList
или жеMap
, TypeTag
потерян".
Вот пример стандартного способа использования Type Tag:
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> trait Animal[T] {
| def typeT()(implicit t: TypeTag[T]) = t.tpe
| }
defined trait Animal
scala>
scala> class Dog extends Animal[Int]
defined class Dog
scala> class Cat extends Animal[String]
defined class Cat
scala>
scala> val dog = new Dog
dog: Dog = Dog@4aa88c93
scala> val cat = new Cat
cat: Cat = Cat@2281e252
scala> dog.typeT
res46: reflect.runtime.universe.Type = Int
scala> cat.typeT
res47: reflect.runtime.universe.Type = String
Как видите, пока все хорошо, методtypeT
определены и внедрены в чертуAnimal
работает. Однако при использовании сList
и экзистенциальные типы, он не работал:
scala> val aa: List[Animal[_]] = List(dog, cat, dog)
aa: List[Animal[_]] = List(Dog@4aa88c93, Cat@2281e252, Dog@4aa88c93)
scala> aa(0).typeT
res52: reflect.runtime.universe.Type = _$1
scala> aa(1).typeT
res53: reflect.runtime.universe.Type = _$1
Явное приведение (как в следующем) наверняка сработало. Но в большинстве случаев этоList[Anima[_]]
, Если нужен другой уровень TypeCast и как?
scala> aa(0)
res55: Animal[_] = Dog@4aa88c93
scala> aa(0).asInstanceOf[Dog]
res56: Dog = Dog@4aa88c93
scala> aa(0).asInstanceOf[Dog].typeT
res57: reflect.runtime.universe.Type = Int
Я это понимаюaa(0)
являетсяAnimal[_]
что является причиной. Но до сих пор,aa(0)
это не толькоAnimal[_]
, ноDog
, ПочемуtypeT
(или жеTypeTag
) не может быть использован, как если бы это был нормальный метод?