使用 scala 2.10 反射对类型参数进行运行时解析

2023-11-26

给定类型声明,我能够解析类型参数。

scala> reflect.runtime.universe.typeOf[List[Int]] match {case x:TypeRef => x.args}
res10: List[reflect.runtime.universe.Type] = List(Int)

对于运行时值,相同的方法不起作用。

scala> reflect.runtime.currentMirror.reflect(List(42)).symbol.toType match {case x:TypeRef => x.args}
res11: List[reflect.runtime.universe.Type] = List(B)

有没有办法克服反射值的类型擦除?


基于阅读中获得的TypeTag知识的示例Scala:什么是 TypeTag 以及如何使用它?发布者尤金·伯马科在对你的问题的评论中:

import scala.reflect.runtime.universe._

object ScalaApplication {
  def main(args: Array[String]) {
    printType(List(42))
    printType(List("42"))
    printType(List("42", 42))
  }    

  def printType[T : TypeTag](t: T) {
    println(typeOf[T])
  }
}

这应该给出输出:

$ scala ScalaApplication.scala 
List[Int]
List[String]
List[Any]

[更新1:]

但是,如果您想了解分配给类型引用的类型Any您可能必须选择某种类型感知包装器:

import scala.reflect.runtime.universe._

object ScalaApplication {
  def main(args: Array[String]) {
    val anyWrapper = new AnyWrapper

    List(1,2,3).foreach { i =>
      i match {
        case 1 => anyWrapper.any = 42
        case 2 => anyWrapper.any = "a string"
        case 3 => anyWrapper.any = true
      }
      print(anyWrapper.any)
      print(" has type ")
      println(anyWrapper.typeOfAny)
    }
  }

  class AnyWrapper {
    private var _any: Any = null
    private var _typeOfAny: Type = null

    def any = _any
    def typeOfAny = _typeOfAny
    def any_=[T: TypeTag](a: T) = {
      _typeOfAny = typeOf[T]
      _any = a
    }

  }
}

这应该给出输出:

$ scala ScalaApplication.scala 
42 has type Int
a string has type String
true has type Boolean

但这个解决方案仍然没有涵盖编译时引用类型未知的情况。

[更新2:]

如果类型显式转换为类型的引用Any,您可能必须枚举 match 语句中所有可能的类型才能恢复类型:

import scala.reflect.runtime.universe._

object ScalaApplication {
  def main(args: Array[String]) {

    List(1,2,3).foreach { i =>
      val any: Any = i match {
        case 1 => 42.asInstanceOf[Any]
        case 2 => "a string".asInstanceOf[Any]
        case 3 => true.asInstanceOf[Any]
      }
      print(any)
      print(" has type ")
      println(matchType(any))
    }
  }

  def matchType(any: Any) = {
    any match {
      case a: Int => typeOf[Int]
      case a: String => typeOf[String]
      case a: Boolean => typeOf[Boolean]
    }
  }
}

这应该给出输出:

$ scala ScalaApplication.scala
42 has type Int
a string has type String
true has type Boolean

但是这个解决方案要求您知道(并列出)您可以在any value.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 scala 2.10 反射对类型参数进行运行时解析 的相关文章

随机推荐