Scala 中的动态代码评估
Dynamic code evaluation in scala
将代码片段注入 Scala 的最佳方法是什么?类似于 javascript 和 GroovyScriptEngine 中的 eval。我想将我的 rules/computations/formulas 保留在实际数据处理之外 class。我有将近 100 多个公式要执行。所有的数据流都是相同的,只是公式发生了变化。在 scala 中最好的方法是什么?公式的数量会随着时间的推移而增加。
您可以使用 scala-lang
API 或 twitter-eval
。这是 scala-lang
的一个简单用例的片段
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.IMain
object ScalaReflectEvaluator {
def evaluate() = {
val clazz = prepareClass
val settings = new Settings
settings.usejavacp.value = true
settings.deprecation.value = true
val eval = new IMain(settings)
val evaluated = eval.interpret(clazz)
val res = eval.valueOfTerm("res0").get.asInstanceOf[Int]
println(res) //yields 9
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
或通过推特:
import com.twitter.util.Eval
object TwitterUtilEvaluator {
def evaluate() = {
val clazz = prepareClass
val eval = new Eval
eval.apply[Int](clazz)
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
我现在无法编译它来检查我是否遗漏了什么,但你应该明白了。
我发现 scala.tools.reflect.ToolBox
是 scala 中最快的 eval(经过测量的解释器、twitter 的 eval 和自定义工具)。这是 API:
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
tb.eval(tb.parse("""println("hello!")"""))
将代码片段注入 Scala 的最佳方法是什么?类似于 javascript 和 GroovyScriptEngine 中的 eval。我想将我的 rules/computations/formulas 保留在实际数据处理之外 class。我有将近 100 多个公式要执行。所有的数据流都是相同的,只是公式发生了变化。在 scala 中最好的方法是什么?公式的数量会随着时间的推移而增加。
您可以使用 scala-lang
API 或 twitter-eval
。这是 scala-lang
import scala.tools.nsc.Settings
import scala.tools.nsc.interpreter.IMain
object ScalaReflectEvaluator {
def evaluate() = {
val clazz = prepareClass
val settings = new Settings
settings.usejavacp.value = true
settings.deprecation.value = true
val eval = new IMain(settings)
val evaluated = eval.interpret(clazz)
val res = eval.valueOfTerm("res0").get.asInstanceOf[Int]
println(res) //yields 9
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
或通过推特:
import com.twitter.util.Eval
object TwitterUtilEvaluator {
def evaluate() = {
val clazz = prepareClass
val eval = new Eval
eval.apply[Int](clazz)
}
private def prepareClass: String = {
s"""
|val x = 4
|val y = 5
|x + y
|""".stripMargin
}
}
我现在无法编译它来检查我是否遗漏了什么,但你应该明白了。
我发现 scala.tools.reflect.ToolBox
是 scala 中最快的 eval(经过测量的解释器、twitter 的 eval 和自定义工具)。这是 API:
import scala.reflect.runtime.universe
import scala.tools.reflect.ToolBox
val tb = universe.runtimeMirror(getClass.getClassLoader).mkToolBox()
tb.eval(tb.parse("""println("hello!")"""))