scala中的动态代码评估

时间:2016-08-25 10:35:21

标签: scala eval scala-collections scalatest

向scala注入一段代码的最佳方法是什么?像javascript和GroovyScriptEngine中的eval之类的东西。我想将我的规则/计算/公式保留在实际的数据处理类之外。我有近100个公式要执行。所有只有公式更改的数据流相同。在scala中执行此操作的最佳方法是什么?公式的数量会随着时间的推移而增长。

2 个答案:

答案 0 :(得分:4)

您可以使用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
  }
}

或使用twitter:

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
  }
}

我目前无法编译它以检查我是否遗漏了一些内容,但你应该明白这一点。

答案 1 :(得分:2)

我发现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!")"""))