This thread解决了与Existential
类型一起使用时如何使用TypeTag
获取类型参数的运行时类型。 Another thread解决了如何将变量转换为从TypeTag
检索的运行时类型。从斯卡拉的存在型TypeCast向运行时类型投入变量
我的问题建立在前面提到的线程上(两种场景的组合)。为了清楚起见,部分代码从两个线程中复制而来。
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
中的正确类型,但不幸的是,由于使用了类型,因此不是TypeTag[Int]
或TypeTag[String]
,而是TypeTag[_]
。有没有解决方案?
编辑1:
尽管字段ttag
是TypeTag[_]
类型的,ttag.tpe
确实有正确的 “类型”(但作为reflect.runtime.universe.Type
一个实例)。是否有可能使用typetag.tpe
投射到正确的类型?
这是一段时间,因为我所访问过这个帖子,但我已经有了一些新的想法返回。我不认为'cast'方法可以像你想要的那样工作,因为'TypeTag'只在运行时才有用,并且在编译时执行。编译器需要知道'cast'的返回类型是什么,但它不能从'TypeTag [_]'中推断出正确的'A'。根据你想要对结果做什么,可能会使它以不同的方式工作。 – 2015-05-15 14:37:10
不仅''cast'处于编译时,'TypeTag'处于运行时,而且由于'存在类型'具有集合,'TypeTag'在'Any'上,而不是它的真实类型。我一直使用的替代方法是使用超类来指示类型,例如'List((Dog,5,IntType),(Cat,“stringgg”,StrType),(Dog,2,IntType))'',然后通过'asInstanceOf'执行一次“运行时”。这个“运行时间”转换在我的练习中非常有用,但它并不安全,我希望有一种编译器时间转换的机制。 – Causality 2015-05-18 23:10:14