56

Scala 可以用来编写 Java 应用程序的脚本吗?

我需要从 Java 加载一段 Scala 代码,为其设置执行范围(主机应用程序公开的数据),评估它并从中检索结果对象。

Scala 文档展示了从 Java 调用编译后的 Scala 代码是多么容易(因为它会变成常规的 JVM 字节码)。

但是我怎样才能动态地评估一个 Scala 表达式(来自 Java,或者如果这更容易,从 Scala 内部)?

对于许多其他语言,有 javax.scripting 接口。Scala 似乎不支持它,我在 Java/Scala 互操作性文档中找不到不依赖提前编译的任何内容。

4

6 回答 6

65

现在是 2011 年,您可以通过scala.tools.nsc.Interpreter 查看http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/来实现

采用scala.tools.nsc.interpreter

于 2011-05-21T15:39:44.307 回答
52

Scala 不是脚本语言。它可能看起来有点像一种脚本语言,人们可能会为此而提倡它,但它并不真正适合 JSR 223 脚本框架(面向动态类型语言)。要回答您最初的问题,Scala 没有eval函数,就像 Java 没有eval. 鉴于它们本质上是静态的,这样的函数对于这两种语言中的任何一种都没有真正意义。

我的建议:重新考虑你的代码,这样你就不需要了eval(你很少这样做,即使在有它的语言中,比如 Ruby)。或者,也许您根本不想在这部分应用程序中使用 Scala。如果您确实需要eval,请尝试使用 JRuby。JRuby、Scala 和 Java 很好地结合在一起。很容易将系统的一部分用 Java,一部分用 Scala,另一部分(需要的部分eval)用 Ruby。

于 2009-07-26T20:20:44.453 回答
21

Scala 在 2.11 ( https://issues.scala-lang.org/browse/SI-874 ) 中添加了对 JSR-223 的官方支持。

因此,如果您在考虑了 Daniel Spiewak 目前接受的答案中的考虑因素(关于以不需要的方式重新思考)之后仍然需要它,那么这应该是官方的替代方案。

于 2013-06-02T14:49:10.080 回答
17

您可以通过获取 scala 代码,将其包装在一个类中,编译该类,使用反射创建一个新实例,然后调用它来模拟“eval”。这有点复杂,而且 scala 编译器的初始化速度非常慢(大约 2 秒),但它工作正常。

这里有一个库,叫做“util-eval”:https ://github.com/twitter/util/

有问题的代码在这里:https ://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala

它是这样工作的:

val sum = Eval[Int]("1 + 1")
// sum will be 2
于 2011-10-31T07:09:14.323 回答
13

我不确定这是否是一个好方法,但我通过使用toolbox.parse和解决了这个问题toolbox.eval

要在 Scala 中进行 eval,您必须:

  1. 导入 scala-reflect

libraryDependencies += "org.scala-lang" % "scala-reflect" % "2.11.7"

  1. 使用工具箱中的 eval:

  import scala.reflect.runtime.currentMirror
  import scala.tools.reflect.ToolBox
  val toolbox = currentMirror.mkToolBox()

  val as = "2*(2+3)"
  val compe = toolbox.eval(toolbox.parse(as))

  println(compe.getClass) // prints class java.lang.Integer
  println(compe) // prints 10

于 2015-06-29T14:13:08.610 回答
2

您始终可以使用 scalac 编译 scala 类,然后动态加载该类。但我想这不是你所追求的。

于 2009-07-28T09:58:03.797 回答