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!")"""))