case class Address( address :String ,pinCode : Int)
case class Person (a: String,b:Int ,c: Address)
def getClassDefinition[T:TypeTag] =
(typeOf[T].members.filter(!_.isMethod).map(r => (r.name -> r.typeSignature)))
val m = getClassDefinition[Address]
(pinCode ,scala.Int)
(address ,String)
val p =getClassDefinition[Person]
(c ,A$A332.this.Address)
(b ,scala.Int)
(a ,String)
我正在寻找一个嵌套的结果,而不是直到地址案例类
答案 0 :(得分:1)
如果我理解了这个问题,那就是获得一个包含名称的类定义 - >类型的每个非方法成员的类型签名对。如果类型签名是标准类型,那就是所需的全部内容;但对于某些类型,需要嵌套定义。我已使用[定义,嵌套定义]或
对这两种情况进行建模在这个例子中,我选择了一个与包名匹配的isNested(...)规则,但它可以是任何标识类以进行更深入检查的规则。
我不确定输出是否符合您的预期格式,但您可以修改示例代码,也可以将结果映射到您自己的数据结构中。
import scala.reflect.runtime.universe._
object TypeTags {
// Define your domain name here for the isNested(...) test!
val myDomainName: String = ???
// Define some type aliases
type Definition = ((AnyRef with SymbolApi)#NameType, Type)
type EitherDefinitionOrNested = Either[Definition, NestedDefinition]
// A nested definition contains the original definition and an iterable collection of its member definitions (recursively).
case class NestedDefinition(t: Definition, m: Iterable[EitherDefinitionOrNested])
// The test to determine if a nested definition is needed.
def isNested(r: Symbol): Boolean = {
r.info.typeSymbol.fullName.startsWith(myDomainName)
}
// Obtain a class definition from a Symbol.
def classDefinition(symbol: Symbol): Iterable[EitherDefinitionOrNested] = {
symbol.typeSignature.members.filter(!_.isMethod).map {
case r @ nested if isNested(r) => Right(NestedDefinition(nested.name -> nested.typeSignature, classDefinition(nested)))
case r => Left(r.name -> r.typeSignature)
}
}
// Obtain a class definition from a type.
def getClassDefinition[T: TypeTag]: Iterable[EitherDefinitionOrNested] = classDefinition(typeOf[T].typeSymbol)
// The test case
case class Address(address: String ,pinCode: Int)
case class Person(a: String, b: Int ,c: Address)
def main(args: Array[String]): Unit = {
val m = getClassDefinition[Address]
val p = getClassDefinition[Person]
println(s"address: $m")
println(s"person: $p")
}
}