56

Scala を使用して Java アプリケーションのスクリプトを作成できますか?

Java から Scala コードの一部をロードし、その実行スコープ (ホスト アプリケーションによって公開されるデータ) を設定し、それを評価して、そこから結果オブジェクトを取得する必要があります。

Scala のドキュメントは、コンパイル済みの Scala コードを Java から呼び出すのがいかに簡単かを示しています (通常の JVM バイトコードに変換されるため)。

しかし、Scala 式をオンザフライで (Java から、またはそれが簡単な場合は Scala 内から) 評価するにはどうすればよいでしょうか?

その他の多くの言語には、javax.scripting インターフェイスがあります。Scala はそれをサポートしていないようで、事前コンパイルに依存しない Java/Scala 相互運用性ドキュメントには何も見つかりませんでした。

4

6 に答える 6

65

現在は 2011 年です。http://blog.darevay.com/2009/01/remedial-scala-interpreting-scala-from-scala/scala.tools.nsc.Interpreterを 参照してください。

使用するscala.tools.nsc.interpreter

于 2011-05-21T15:39:44.307 に答える
52

Scala はスクリプト言語ではありません。それはスクリプト言語のように見えるかもしれませんし、人々はその目的のためにそれを支持するかもしれませんが、JSR 223 スクリプト フレームワーク (動的に型付けされた言語に向けられている) にはあまり適合しません。元の質問に答えるために、evalJava にeval. そのような関数は、本質的に静的な性質を考えると、これらの言語のいずれに対しても意味をなさないでしょう。

私のアドバイス: 必要がないようにコードを再考してくださいeval(Ruby のようにコードを持っている言語であっても、めったにそうしません)。または、アプリケーションのこの部分に Scala をまったく使用したくない場合もあります。本当に必要な場合はeval、JRuby を使用してみてください。JRuby、Scala、および Java は非常にうまく連携しています。システムの一部を Java で、一部を Scala で、別の部分 (必要な部分eval) を Ruby で作成するのは非常に簡単です。

于 2009-07-26T20:20:44.453 に答える
21

Scala は 2.11 で JSR-223 の公式サポートを追加しました ( https://issues.scala-lang.org/browse/SI-874 )。

そのため、現在受け入れられている 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.parsetoolbox.eval

Scala で eval を行うには、次のことを行う必要があります。

  1. import 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 に答える