在scala 2.11中反映案例类字段的最佳方法?

Gre*_*reg 6 reflection scala

我想(静态)反映一个这样的示例类:

case class Foo[T,U](stuff:T, more:U, age:Int) {
  val ignore:Boolean = false
}
Run Code Online (Sandbox Code Playgroud)

我开始是这样的:

val symbol = currentMirror.classSymbol(clazz)   // symbol is universe.ClassSymbol
// I want to know about type placeholders T and U
val typeParamArgs = symbol.typeParams.map( tp => tp.name.toString)
if( symbol.isCaseClass ) {
  val tsig = symbol.typeSignature
  println(tsig)
}
Run Code Online (Sandbox Code Playgroud)

好的,此时如果我打印tsig,我看到:

[T, U]scala.AnyRef
        with scala.Product
        with scala.Serializable {
  val stuff: T
  private[this] val stuff: T
  val more: U
  private[this] val more: U
  val age: scala.Int
  private[this] val age: scala.Int
  def <init>(stuff: T,more: U,age: scala.Int): co.blocke.Foo[T,U]
  val ignore: scala.Boolean
  private[this] val ignore: scala.Boolean
  def copy[T, U](stuff: T,more: U,age: scala.Int): co.blocke.Foo[T,U]
  def copy$default$1[T, U]: T @scala.annotation.unchecked.uncheckedVariance
  def copy$default$2[T, U]: U @scala.annotation.unchecked.uncheckedVariance
  def copy$default$3[T, U]: scala.Int @scala.annotation.unchecked.uncheckedVariance
  override def productPrefix: java.lang.String
  def productArity: scala.Int
  def productElement(x$1: scala.Int): scala.Any
  override def productIterator: Iterator[scala.Any]
  def canEqual(x$1: scala.Any): scala.Boolean
  override def hashCode(): scala.Int
  override def toString(): java.lang.String
  override def equals(x$1: scala.Any): scala.Boolean
}
Run Code Online (Sandbox Code Playgroud)

用<init>查看中间的那一行?那是我想要反省的宣言.它有我需要的东西.

如何选择tsig(universe.Type)来获取有关<init>的信息? (我不想要关于'忽略'的信息.)

Dan*_*etz 3

不检查类的.typeSignature,而是使用以下命令检查构造函数的类型签名.primaryConstructor.typeSignature

val csig = symbol.primaryConstructor.typeSignature
val params = csig.paramLists.head  // paramLists returns a List of Lists
Run Code Online (Sandbox Code Playgroud)

这将为您提供主构造函数的参数列表,以便您可以查询名称、类型等:

scala> params(1).name
res47: reflect.runtime.universe.Symbol#NameType = more

scala> params(2).typeSignature
res48: reflect.runtime.universe.Type = scala.Int
Run Code Online (Sandbox Code Playgroud)