在 scala 2.11 中反映 case class 字段的最佳方式?
Best way to reflect case class fields in scala 2.11?
我想(静态)反映一个样本 class 像这样:
case class Foo[T,U](stuff:T, more:U, age:Int) {
val ignore:Boolean = false
}
我是这样开始的:
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)
}
好的,此时如果我打印 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[T, U]: T @scala.annotation.unchecked.uncheckedVariance
def copy$default[T, U]: U @scala.annotation.unchecked.uncheckedVariance
def copy$default[T, U]: scala.Int @scala.annotation.unchecked.uncheckedVariance
override def productPrefix: java.lang.String
def productArity: scala.Int
def productElement(x: scala.Int): scala.Any
override def productIterator: Iterator[scala.Any]
def canEqual(x: scala.Any): scala.Boolean
override def hashCode(): scala.Int
override def toString(): java.lang.String
override def equals(x: scala.Any): scala.Boolean
}
看到中间那行了吗?这就是我要反省的声明。它有我需要的东西。
如何分离 tsig (universe.Type) 以获取有关 的信息? (我不想要有关 'ignore' 的信息。 )
不是检查 class 的 .typeSignature
,而是使用 .primaryConstructor.typeSignature
:
检查构造函数的类型签名
val csig = symbol.primaryConstructor.typeSignature
val params = csig.paramLists.head // paramLists returns a List of Lists
这里给你一个主构造函数的参数列表,你可以查询名称、类型等:
scala> params(1).name
res47: reflect.runtime.universe.Symbol#NameType = more
scala> params(2).typeSignature
res48: reflect.runtime.universe.Type = scala.Int
我想(静态)反映一个样本 class 像这样:
case class Foo[T,U](stuff:T, more:U, age:Int) {
val ignore:Boolean = false
}
我是这样开始的:
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)
}
好的,此时如果我打印 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[T, U]: T @scala.annotation.unchecked.uncheckedVariance
def copy$default[T, U]: U @scala.annotation.unchecked.uncheckedVariance
def copy$default[T, U]: scala.Int @scala.annotation.unchecked.uncheckedVariance
override def productPrefix: java.lang.String
def productArity: scala.Int
def productElement(x: scala.Int): scala.Any
override def productIterator: Iterator[scala.Any]
def canEqual(x: scala.Any): scala.Boolean
override def hashCode(): scala.Int
override def toString(): java.lang.String
override def equals(x: scala.Any): scala.Boolean
}
看到中间那行
如何分离 tsig (universe.Type) 以获取有关
不是检查 class 的 .typeSignature
,而是使用 .primaryConstructor.typeSignature
:
val csig = symbol.primaryConstructor.typeSignature
val params = csig.paramLists.head // paramLists returns a List of Lists
这里给你一个主构造函数的参数列表,你可以查询名称、类型等:
scala> params(1).name
res47: reflect.runtime.universe.Symbol#NameType = more
scala> params(2).typeSignature
res48: reflect.runtime.universe.Type = scala.Int