从Scala中的存在类型TypeCast将变量转换为运行时类型

时间:2015-04-01 20:43:48

标签: scala types casting existential-type

This thread解决了与TypeTag类型一起使用时如何使用Existential获取运行时类型参数的方法。 Another thread解决了如何将变量强制转换为从TypeTag检索到的运行时类型。

我的问题建立在前面提到的线程(两种场景的组合)之上。为清楚起见,部分代码是从两个线程中复制的。

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> def cast[A](a: Any, tt: TypeTag[A]): A = a.asInstanceOf[A]
cast: [A](a: Any, tt: reflect.runtime.universe.TypeTag[A])A

scala> abstract class Animal[T](implicit tt: TypeTag[T]) {
     |   val ttag = tt
     | }
defined class Animal

scala> case object Dog extends Animal[Int]
defined object Dog

scala> case object Cat extends Animal[String]
defined object Cat

scala> val aa: List[(Animal[_], Any)] = List((Dog, 5), (Cat, "stringgg"), (Dog, 2))                                                                                                               
aa: List[(Animal[_], Any)] = List((Dog,5), (Cat,stringgg), (Dog,2))

scala> aa(0)._1.ttag
res25: reflect.runtime.universe.TypeTag[_] = TypeTag[Int]

scala> aa(1)._1.ttag
res26: reflect.runtime.universe.TypeTag[_] = TypeTag[String]

scala> cast(aa(0)._2, aa(0)._1.ttag)
res27: Any = 5

scala> cast(aa(1)._2, aa(1)._1.ttag)
res28: Any = stringgg

简而言之,最后两行:cast(value, TypeTag[_])始终返回Any类型的值。但我的目的是将这些值转换为Dog|Cat.ttag中存储的正确类型,由于{{1}的使用,遗憾的是,它不是TypeTag[Int]TypeTag[String]而是TypeTag[_] }类型。它有什么解决方案吗?

编辑1:

尽管字段existential的类型为ttag,但TypeTag[_]确实具有正确的“类型”(但作为ttag.tpe的实例)。是否可以使用reflect.runtime.universe.Type转换为正确的类型?

1 个答案:

答案 0 :(得分:0)

你可以改变施法方法, def cast[A](a: Any, tt: TypeTag[_]): A = a.asInstanceOf[A]

val x: Int = cast(aa(0)._2, aa(0)._1.ttag)