我试图动态地解释作为字符串给出的代码。
例如:
val myString = "def f(x:Int):Int=x+1".
我正在寻找一种可以从中返回实际功能的方法:
例如:
val myIncrementFunction = myDarkMagicFunctionThatWillBuildMyFunction(myString)
println(myIncrementFunction(3))
将打印 4
用例:我想稍后在我的代码中使用该解释代码中的一些简单函数。例如,他们可以提供类似 def fun(x: Int): Int = x + 1 作为字符串的东西,然后我使用解释器来编译/执行该代码,然后我希望能够使用这个 fun(x ) 例如在 map 中。
问题是该函数类型对我来说是未知的,这是大问题之一,因为我需要从 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作品。
您知道我如何实现此功能的任何方法吗?
我是新手,写错了还请见谅。
谢谢
最佳答案
好的,我设法实现了我想要的功能,我仍在寻找改进此代码的方法,但是此代码段满足了我的要求。
我使用了 Scala 工具箱和 quasiquotes
import scala.reflect.runtime.universe.{Quasiquote, runtimeMirror}
import scala.tools.reflect.ToolBox
object App {
def main(args: Array[String]): Unit = {
val mirror = runtimeMirror(getClass.getClassLoader)
val tb = ToolBox(mirror).mkToolBox()
val data = Array(1, 2, 3)
println("Data before function applied on it")
println(data.mkString(","))
println("Please enter the map function you want:")
val function = scala.io.StdIn.readLine()
val functionWrapper = "object FunctionWrapper { " + function + "}"
val functionSymbol = tb.define(tb.parse(functionWrapper).asInstanceOf[tb.u.ImplDef])
// Map each element using user specified function
val dataAfterFunctionApplied = data.map(x => tb.eval(q"$functionSymbol.function($x)"))
println("Data after function applied on it")
println(dataAfterFunctionApplied.mkString(","))
}
}
这是终端中的结果:
Data before function applied on it
1,2,3
Please enter the map function you want:
def function(x: Int): Int = x + 2
Data after function applied on it
3,4,5
Process finished with exit code 0
关于scala - 使用反射和解释器动态解析字符串并在 Scala 中返回一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34612322/