ケースクラスのコンストラクターフィールドを深く歩くコードがありますが、もちろんそれ自体が複雑な場合があります (モノ、マップ、オプション、およびその他のケースクラスのリスト)。実行時にフィールド値を抽出するために見つけたコードは、最高レベルのフィールドではうまく機能しますが、より深いフィールドにアクセスしようとすると爆発します。以下の例。
私の実生活では、アプリケーションが各レベルのフィールドを内省しているので、「もの」が別のケースクラスであることを知っており (シンボル/タイプを持っています)、Dos のフィールドのシンボル/タイプを知っています。でもこれは実行時に取得するので、[T]/Manifest[T]がわからないのでぶっ飛んでいると思います。リフレクションを介して実行時にこれを取得する方法はありますか? コードはどのように変更される可能性がありますか? 私が見つけた例はすべてさまざまなものを必要とするように見えました[T]、「dos」には必要ありませんよね?
case class Uno( name:String, age:Int, pets:List[String], stuff:Dos )
case class Dos( foo:String )
object Boom extends App {
val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val u = Uno("Marcus",19,List("fish","bird"),Dos("wow"))
println("NAME: "+unpack(u,"name")) // Works
println("PETS: "+unpack(u,"pets")) // Works
// ----- Goes Boom -------
val dos = unpack(u,"stuff")
println("Other: "+unpack(dos,"foo")) // Boom!
// -----------------------
// Get object value for named parameter of target
def unpack[T]( target:T, name:String )(implicit man:Manifest[T]) : Any = {
val im = m.reflect(target)
val fieldX = ru.typeOf[T].declaration(ru.newTermName(name)).asTerm.accessed.asTerm
im.reflectField(fieldX).get
}
}