22

使用类型标签,我可以看到某种类型的参数:

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

scala> typeOf[List[Int]]
res0: reflect.runtime.universe.Type = List[Int]

但我只是不太清楚如何以一般方式以编程方式将“Int”从那里取出。

(我现在已经在 REPL 中徘徊了一个小时,尝试对 Type 进行排列,看看我能从中获得什么......我得到了很多表明这是一个“列表”的东西,但祝你好运找到那个“Int”!而且我真的不想求助于解析 toString() 输出......)

Daniel Sobral 在这里有一个很好的(和往常一样)快速概述,其中他非常接近我正在寻找的东西,但(显然)只有当你碰巧知道,对于那个特定的类,一些特定的方法,其类型可以是审问:

scala> res0.member(newTermName("head"))
res1: reflect.runtime.universe.Symbol = method head

scala> res1.typeSignatureIn(res0)
res2: reflect.runtime.universe.Type = => Int

但我希望有一些更通用的东西,它不涉及在声明的方法列表中查找并希望其中一个能够在某处捕获(并因此泄露)标签的当前类型信息。

如果 Scala 可以如此轻松地打印“List[Int]”,为什么在不借助字符串模式匹配的情况下,很难发现其中的“Int”部分?还是我只是错过了一些非常非常明显的东西?

scala> res0.typeSymbol.asInstanceOf[ClassSymbol].typeParams
res12: List[reflect.runtime.universe.Symbol] = List(type A)

scala> res12.head.typeSignatureIn(res0)
res13: reflect.runtime.universe.Type = 

呸...

4

2 回答 2

16

从 开始Scala 2.11,您可以简单地使用:

yourGenericType.typeArgs.head

请参阅宏更改日志点编号 14。

于 2014-05-01T12:41:18.940 回答
14

可悲的是,我认为没有一种方法可以为您提供参数,但您可以通过以下方式获取它们:

Welcome to Scala version 2.10.0-20121007-145615-65a321c63e (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.

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

scala> typeOf[List[Int]]
res0: reflect.runtime.universe.Type = scala.List[Int]

scala> res0 match { case TypeRef(_, _, args) => args }
res1: List[reflect.runtime.universe.Type] = List(Int)

scala> res1.head
res2: reflect.runtime.universe.Type = Int

编辑 这里有一个更好的方法来实现同样的事情(在讨论 scala-internals之后):

scala> res0.asInstanceOf[TypeRefApi].args
res1: List[reflect.runtime.universe.Type] = List(Int)
于 2012-10-11T15:59:14.893 回答