2

私はこの質問の受け入れられた答えを使用して、値の配列からケースクラスを構築するための小さなヘルパークラスを構築しました: パラメーターのコレクションからケースクラスを構築します

回答で述べたように、内部ケースクラスは機能しません。あなたは

ScalaReflectionException: class X is an inner class, use reflectClass on an InstanceMirror to obtain its ClassMirror  

例外が説明しているように、InstanceMirrorの使用方法を理解するのに問題があります。これが私の現在のREPL可能なコードです(キャッシュのために必要以上に少し複雑です)。

import scala.reflect.runtime.universe._ 

object ReflectUtil {
  private val constructorCache = collection.mutable.HashMap[String, MethodMirror]()

  def constructFromSeq[T: TypeTag](args: Seq[Any]): T = {
    val tag = typeTag[T]
    val strTag = tag.toString
    var constructorMirror = constructorCache.getOrElseUpdate( strTag, {
      val rm = runtimeMirror(getClass.getClassLoader)
      val classSymbol = tag.tpe.typeSymbol.asClass
      val classMirror = rm.reflectClass(classSymbol) // wrap with try/catch?
      val constructorSymbol = tag.tpe.declaration(nme.CONSTRUCTOR).asMethod
      classMirror.reflectConstructor(constructorSymbol)
    })
    constructorMirror(args: _*).asInstanceOf[T]
  } 
}   

case class X(a:String, b:Int)

class Out { 
  case class Y(a:String, b:Int) 

  def buildY(arr:Array[Any]) = {
    ReflectUtil.constructFromSeq[Y](arr)
  }
}

val arr = Array[Any]("asdf", 1234)
ReflectUtil.constructFromSeq[X](arr) // this works

val inst = new Out
inst.buildY(arr) // this doesn't work
4

1 に答える 1

4

例外は、内部クラスのインスタンスを構築するために外部参照が必要であることを意味します(たとえば、構築Yするにはのインスタンスが必要ですOut)。その後、あなたはすることができますrm.reflect(instanceOfOut).reflectClass...

于 2013-02-24T19:08:45.027 に答える