У меня проблемы с вложенными списками и отражением Scala.Scala Отражение вложенного списка
Как я могу исследовать поле класса case типа List[List[something]]
?
Некоторые коды здесь. Он лишен - в реальной жизни он создает статические данные об отраженном классе. Интересная часть - inspectField
.
import reflect.runtime.currentMirror
import reflect.runtime.universe._
case class Pet(val name: String, val legs: Int)
case class ListList2(val name: String, val stuff: List[List[Pet]])
object Boom extends App {
// Introspect class and find all its members (constructor fields)
val symbol = currentMirror.classSymbol(Class.forName("com.br.ListList2"))
val constructor = symbol.toType.members.collectFirst {
case method: MethodSymbol if method.isPrimaryConstructor && method.isPublic && !method.paramss.isEmpty && !method.paramss.head.isEmpty => method
}.getOrElse(throw new IllegalArgumentException("Case class must have at least 1 public constructor having more than 1 parameters."))
// Loop through each field
constructor.paramss.head.map(c => inspectField(c))
private def inspectField[T](sym:Symbol) : String = {
val cname = sym.name.toString
println("Field: "+cname)
val cType = sym.typeSignature
if(cType.typeSymbol.fullName.toString == "scala.collection.immutable.List") {
println("C: "+cType)
val subtype = cType.asInstanceOf[TypeRef].args(0) // Goes boom here on first recursive call
println("Sub:"+subtype)
inspectField(subtype.typeSymbol)
}
"Hi"
}
}
Мой случай класс определяет поле типа List[List[Animal]]
. Я ожидаю, что мой код inspectField
будет называться рекурсивно. Первый раз без проблем. Он печатает:
Field: name
Field: stuff
C: scala.List[scala.List[com.br.Pet]]
Sub:scala.List[com.br.Pet]
До сих пор это то, что я ожидаю. Теперь по рекурсивному вызову inspectField
, на этот раз прохождение subtype
первого звонка (List[Pet])
. Я ожидал, что выход так:
Field: stuff
C: scala.List[com.br.Pet]
Sub:com.br.Pet
Вместо этого идет бум с ошибкой, где отмечено:
Exception in thread "main" java.lang.ClassCastException: scala.reflect.internal.Types$PolyType cannot be cast to scala.reflect.api.Types$TypeRefApi
Очень круто, спасибо! – Greg