动态解析字符串并使用反射和解释器在scala中返回一个函数

前端之家收集整理的这篇文章主要介绍了动态解析字符串并使用反射和解释器在scala中返回一个函数前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
@H_404_1@
我试图用dinamically来解释作为String给出的代码.
例如:

val myString = "def f(x:Int):Int=x+1".

我正在寻找一种方法,它将从中返回真正的函数
例如:

val myIncrementFunction = myDarkMagicFunctionThatWillBuildMyFunction(myString)
println(myIncrementFunction(3))

将打印4

使用案例:我希望稍后在代码中使用该解释代码中的一些简单函数.例如,他们可以提供类似def fun(x:Int)的东西:Int = x 1作为字符串,然后我使用解释器来编译/执行该代码,然后我希望能够使用这个有趣的(x)例如,在地图中.

问题是这个函数类型对我来说是未知的,这是一个很大的问题因为我需要从IMain回来.
我读过有关反射,类型系统等的内容,经过一些谷歌搜索,我达到了这一点.我还检查了twitter的util-eval但是我从他们的测试中的文档和示例中看不到太多,这是完全相同的.

如果我知道我可以做类似的类型

val settings = new Settings
val imain = new IMain(settings)
val res = imain.interpret("def f(x:Int):Int=x+1; val ret=f _ ")
val myF = imain.valueOfTerm("ret").get.asInstanceOf[Function[Int,Int]]
println(myF(2))

哪个工作正常并打印3但我被上面说的问题阻止,我不知道函数的类型,这个例子的作用只是因为我在我定义字符串函数测试IMain时使用的类型作品.

你知道如何实现这个功能吗?

我是新手,所以如果我写错了,请原谅我.

谢谢

解决方法

您可以使用twitter-util库来执行此操作,检查测试文件
https://github.com/twitter/util/blob/develop/util-eval/src/test/scala/com/twitter/util/EvalTest.scala

如果你需要使用IMain,也许是因为你想在自己的自定义设置中使用intepreter,你可以这样做:

一个.首先创建一个用于保存结果的类:

class ResHolder(var value: Any)

湾创建一个容器对象来保存结果并将代码解释为该对象:

val settings = new Settings()
    val writer = new java.io.StringWriter()
    val interpreter = new IMain(settings,writer)

    val code = "def f(x:Int):Int=x+1"

    // Create a container object to hold the result and bind in the interpreter
    val holder = new ResHolder(null) 

    interpreter.bind("$result",holder.getClass.getName,holder) match {
       case Success => 
       case Error => throw new ScriptException("error in: binding '$result' value\n" + writer)
       case Incomplete => throw new ScriptException("incomplete in: binding '$result' value\n" + writer)
    }

    val ir = interpreter.interpret("$result.value = " + code)

    // Return cast value or throw an exception based on result
    ir match {
       case Success =>
          val any = holder.value
          any.asInstanceOf[(Int) => Int]

       case Error => throw new ScriptException("error in: '" + code + "'\n" + writer)
       case Incomplete => throw new ScriptException("incomplete in :'" + code + "'\n" + writer)
    }

猜你在找的Scala相关文章