2015-04-01 79 views
2

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:

尽管字段ttagTypeTag[_]类型的,ttag.tpe确实有正确的 “类型”(但作为reflect.runtime.universe.Type一个实例)。是否有可能使用typetag.tpe投射到正确的类型?

+1

这是一段时间,因为我所访问过这个帖子,但我已经有了一些新的想法返回。我不认为'cast'方法可以像你想要的那样工作,因为'TypeTag'只在运行时才有用,并且在编译时执行。编译器需要知道'cast'的返回类型是什么,但它不能从'TypeTag [_]'中推断出正确的'A'。根据你想要对结果做什么,可能会使它以不同的方式工作。 – 2015-05-15 14:37:10

+0

不仅''cast'处于编译时,'TypeTag'处于运行时,而且由于'存在类型'具有集合,'TypeTag'在'Any'上,而不是它的真实类型。我一直使用的替代方法是使用超类来指示类型,例如'List((Dog,5,IntType),(Cat,“stringgg”,StrType),(Dog,2,IntType))'',然后通过'asInstanceOf'执行一次“运行时”。这个“运行时间”转换在我的练习中非常有用,但它并不安全,我希望有一种编译器时间转换的机制。 – Causality 2015-05-18 23:10:14

回答

0

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

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

虽然我不认为这回答OP的问题。然后,您必须手动告诉编译器“A”是什么,我只想从TypeTag中派生出来。 – 2015-04-02 13:04:05

+0

@ m-z问题是,cast被推断为Nothing。 – 2015-04-03 04:20:01