Java Scala 中的“评估”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1183645/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 00:36:58  来源:igfitidea点击:

"eval" in Scala

javascalascriptingembedding

提问by Thilo

Can Scala be used to script a Java application?

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

I need to load a piece of Scala code from Java, set up an execution scope for it (data exposed by the host application), evaluate it and retrieve a result object from it.

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

The Scala documentation shows how easy it is to call compiled Scala code from Java (because it gets turned into to regular JVM bytecode).

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

But how can I evaluate a Scala expression on the fly (from Java or if that is easier, from within Scala) ?

但是我怎样才能即时评估 Scala 表达式(从 Java 或者如果更容易,从 Scala 内部)?

For many other languages, there is the javax.scripting interface. Scala does not seem to support it, and I could not find anything in the Java/Scala interoperability docs that does not rely on ahead-of-time compilation.

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

采纳答案by Daniel Spiewak

Scala is not a scripting language. It may looksomewhat like a scripting language, and people may advocate it for that purpose, but it doesn't really fit well within the JSR 223 scripting framework (which is oriented toward dynamically typed languages). To answer your original question, Scala does not have an evalfunction just like Java does not have an eval. Such a function wouldn't really make sense for either of these languages given their intrinsically static nature.

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

My advice: rethink your code so that you don't need eval(you rarely do, even in languages which have it, like Ruby). Alternatively, maybe you don't want to be using Scala at all for this part of your application. If you really need eval, try using JRuby. JRuby, Scala and Java mesh very nicely together. It's quite easy to have part of your system in Java, part in Scala and another part (the bit which requires eval) in Ruby.

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

回答by Kim Stebel

You can always use scalac to compile a scala class and then load that class dynamically. But I guess that's not what you're after.

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

回答by ninjagecko

it's now 2011, and you can do so with scala.tools.nsc.Interpreter

现在是 2011 年,你可以这样做 scala.tools.nsc.Interpreter

see http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/

http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/

回答by Robey Pointer

You can emulate "eval" by taking scala code, wrapping it in a class, compiling that class, using reflection to create a new instance, and then calling it. It's a little involved, and the scala compiler is very slow (on the order of 2 seconds) to initialize, but it works fine.

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

There's a library for it here, called "util-eval": https://github.com/twitter/util/

这里有一个名为“util-eval”的库:https: //github.com/twitter/util/

The code in question lives here: https://github.com/twitter/util/blob/master/util-eval/src/main/scala/com/twitter/util/Eval.scala

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

It works like this:

它是这样工作的:

val sum = Eval[Int]("1 + 1")
// sum will be 2

回答by Oswaldo

Scala has added official support to JSR-223 in 2.11 (https://issues.scala-lang.org/browse/SI-874).

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

So if you still need it after thinking about the considerations made in the currently accepted answer from Daniel Spiewak (about rethinking in a way it is not needed), this should be the official alternative.

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

回答by gun

I am not sure, if this is a good way, but I solved this problem with using toolbox.parseand toolbox.eval

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

To have an eval in Scala you have to:

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

  1. Import scala-reflect
  1. 导入标度反射

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

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

  1. Use eval from toolbox:
  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