案例类的TypeTag

时间:2017-04-10 17:17:21

标签: scala reflection case-class scala-reflect reify

我想创建一个带有类型参数Bla的案例类A,它在运行时知道A的类型(它将它存储在info中领域)。

我的尝试显示在下面的示例中。问题是这个例子没有编译。

case class Bla[A] (){
  val info=Run.paramInfo(this) // this does not compile
}
import scala.reflect.runtime.universe._

object Run extends App{
  val x=Bla[Int]
  def paramInfo[T](x:T)(implicit tag: TypeTag[T]): String = {
    val targs = tag.tpe match { case TypeRef(_, _, args) => args }
    val tinfo=s"type of $x has type arguments $targs"
    println(tinfo)
    tinfo
  }
  paramInfo(x)
}

然而,当我评论val info=Run.paramInfo(this)时,程序运行正常并打印:

  

Bla()的类型具有类型参数List(Int)

有没有办法让这个例子在下面编译? (或者以某种其他方式实现相同的目标,即案例类是否自己知道它的类型参数的类型?)

2 个答案:

答案 0 :(得分:3)

使用基于反射的API没有什么意义,shapeless有一个类型类,它使用隐式宏将编译时信息暴露给运行时。

import shapeless.Typeable


class Test[T : Typeable] {
  def info: String = implicitly[Typeable[T]].describe
}

在这里推送自己的东西也相对容易,但是在不同的编译单元中编译隐式宏比使用它时更加不方便。

答案 1 :(得分:2)

您只需要将隐式类型标记参数传递给case类构造函数(否则在调用需要它的paraInfo之前类型信息会丢失):

case class Bla[A : TypeTag]() { ... }

这是简写:

case class Bla[A](implicit tag: TypeTag[A]) { ... }