Tipo de tempo de execução de característica do parâmetro type por TypeTag quando usado com o tipo Existential no Scala
eu tenhotrait
com o parâmetro type Para obter o tipo de tempo de execução, eu usoTypeTag
. No entanto, quando estetrait
(e suas classes) são usadas comexistential type
em uma coleção, por exemploList
ouMap
, TypeTag
está perdido".
Aqui está um exemplo da maneira padrão de usar a tag de tipo:
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
Como você pode ver, até agora tudo bem, o métodotypeT
definido e implementado na característicaAnimal
trabalho. No entanto, quando usado comList
existenciais, falhou ao trabalhar:
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
Fundição explícita (como a seguir) com certeza funcionou. Mas na maioria das vezes o que é dado éList[Anima[_]]
. Se outro nível de TypeCast for necessário, e como?
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
Eu entendi aquiloaa(0)
é umAnimal[_]
qual é a razão Mas ainda,aa(0)
não é apenas umAnimal[_]
, mas umDog
. Porque otypeT
(ouTypeTag
) não pôde ser usado como se fosse um método normal?