在 Scala 2.10 中通过反射查找类型参数? [英] Finding type parameters via reflection in Scala 2.10?

查看:61
本文介绍了在 Scala 2.10 中通过反射查找类型参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Using type tags, I'm able to see the parameters of some type:

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

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

但我只是无法弄清楚如何以一般方式以编程方式将Int"从那里取出.

But I just can't quite figure out how to programmatically get that "Int" out of there, in a general way.

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

(I've been wandering around in REPL for an hour now, trying permutations on Type, to see what I can obtain from it... I get a lot of things which indicate this is a "List", but good luck on finding that "Int"! And I don't really want to resort to parsing the toString() output...)

Daniel Sobral 有一个很棒的(像往常一样)快速概览这里,其中他非常接近我正在寻找的东西,但(显然)只有当您碰巧知道,对于该特定类,可以询问其类型的某些特定方法时:

Daniel Sobral has an excellent (as usual) quick overview here, in which he gets tantalizingly close to what I'm looking for, but (apparently) only if you happen to know, for that particular class, some specific method whose type can be interrogated:

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

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

但我希望有一些更通用的东西,它不涉及在声明的方法列表中扎根,并希望其中一个会在某处捕获(从而泄露)标签的当前类型信息.

But I'm hoping for something more general, which doesn't involve rooting around in the list of declared methods and hoping that one of them will capture (and thus divulge) the tag's current type information somewhere.

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

If Scala can so easily print "List[Int]", why on earth is it so hard to discover that "Int" part of that -- without resorting to string pattern matching? Or am I just missing something really, really obvious?

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 = 

呜呜……

推荐答案

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

Sadly, I don't think that there's a method that will give you the parameters, but you can get hold of them this way:

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 的讨论):

Edit Here's a slightly nicer way to achieve the same thing (following a discussion on scala-internals):

scala> res0.asInstanceOf[TypeRefApi].args
res1: List[reflect.runtime.universe.Type] = List(Int)

这篇关于在 Scala 2.10 中通过反射查找类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆