2016-11-10 84 views
1

我想在scala中實現一個函數,它可以解析源代碼(類對象)的字符串並在運行時將其編譯爲對象。Scala解析字符串類並在運行時編譯

例如,該功能是我迄今爲止所嘗試的功能。我的目標是運行它在運行時環境編譯,我可以使用它的構造函數或它的函數。此代碼有運行時錯誤,但我不明白如何解決反射類錯誤。謝謝!

object test { 
     def main(args: Array[String]): Unit = { 
      val m = universe.runtimeMirror(getClass.getClassLoader) 
      val tb = m.mkToolBox() 
      val clazz = tb.compile(tb.parse("class insideclass {\n val model_field = 5\n def insideclass(model: Int) = {\n  val model_field = model \n } \n\n def test() : Int = {\n  model_field\n }\n\n}\nscala.reflect.classTag[insideclass].runtimeClass"))().asInstanceOf[Class[_]] 
      val classinside = universe.typeOf[Class[_]].typeSymbol.asClass 
      val ctor = universe.typeOf[Class[_]].declaration(universe.nme.CONSTRUCTOR).asMethod 
      val cm=m.reflectClass(classinside) 
      val ctorm=cm.reflectConstructor(ctor) 
      println(ctorm(10).test()) 
     } 
    } 

回答

1

問題是外部編譯器不知道「內部類」作爲類定義存在。一種解決方案是讓內部類擴展一些對於內部和外部編譯器都知道的其他類,例如Function [Int,Int]。在這種情況下,您需要將您的「測試」方法重命名爲「應用」。

val clazz = tb.compile(tb.parse("class PersonData(x:Int) extends Function[Int, Int] {\n val allen = x.toInt\n\n override def apply(x:Int):Int = allen}\n scala.reflect.classTag[PersonData].runtimeClass"))().asInstanceOf[Class[_]] 

val ctor = clazz.getDeclaredConstructors()(0) 

val instance = ctor.newInstance(new Integer(1)) 
// this cast can succeed because the outside knows what is Function[Int, Int] 
println(instance.asInstanceOf[Function[Int, Int]].apply(1))