【问题标题】:Using Scala reflection to find most derived runtime type使用 Scala 反射查找大多数派生的运行时类型
【发布时间】:2013-06-09 13:42:36
【问题描述】:

我正在尝试使用 Scala 2.10 反射来查找最派生的方法参数类型。例如,考虑这个程序:

import reflect.runtime.universe._

object ReflectionTest {

  def checkType[A : TypeTag](item: A) {
    println("typeOf[A]: " + typeOf[A])
  }

  def main(args: Array[String]) {
    val a = Array(1, "Hello")
    for (item <- a) checkType(item)
  }
}

这里a 的类型为Array[Any],因此发送到checkType 的每个项目都具有Any 类型。结果,checkType 输出

typeOf[A]: Any
typeOf[A]: Any

这对我来说很有意义,因为 TypeTag 是由编译器在调用时生成的(它所知道的关于类型的所有信息都是 Any)。然而,我想要的是确定每个项目的实际类型。我想输出一些类似的东西

Int
String

我已经查看了这里的文档

http://docs.scala-lang.org/overviews/reflection/overview.html

但是样本似乎没有涵盖这种情况,我发现那里关于环境、宇宙和镜子的讨论很难理解。看起来我正在尝试做的事情应该相当简单,但也许我完全错误地接近它。

【问题讨论】:

  • 如果没有某种编译时信息(类型标签),您无法从反射中检索未擦除的类型,因为在 JVM 上运行时只存在已擦除的类型,所以@tenshi 的答案是您能做的最好的.超越这一点的唯一方法是将数组中每个元素的类型标记存储在另一个数据结构中。

标签: scala reflection


【解决方案1】:

最明显的解决方案是使用类:

def checkType[A](item: A) {
  println("typeOf[A]: " + item.getClass)
}

但如果您想使用Type,则需要做一些额外的工作:

def checkType[A](item: A) {
  val mirror = runtimeMirror(this.getClass.getClassLoader)
  println("typeOf[A]: " + mirror.classSymbol(item.getClass).toType)
}

【讨论】:

  • 谢谢,@tenshi,这很有帮助。我实际上是在尝试用数组来做到这一点。我注意到您的解决方案似乎正在返回已擦除的类型。我还需要访问数组的元素类型。我不确定是否有一个简单的解决方法......我会继续挖掘。
猜你喜欢
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
相关资源
最近更新 更多