1

我想创建一个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)

有没有办法让下面的这个例子编译?(或以其他方式实现相同的目标,即案例类自我意识到其类型参数的类型?)

4

2 回答 2

3

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

import shapeless.Typeable


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

在这里滚动你自己的东西也相对容易,但不得不在与使用它的任何编译单元不同的编译单元中编译隐式宏,这增加了不便。

于 2017-04-10T17:53:13.813 回答
2

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

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

这是以下的简写:

case class Bla[A](implicit tag: TypeTag[A]) { ... }
于 2017-04-10T17:45:50.213 回答