0

実行時に Groovy の「プラグイン」クラスをロードする scala アプリケーションを作成しています。プラグインが読み込まれると、標準の scala 型 (Listや などOption) が処理のためにプラグインに渡されます。

Groovy には当然、scala 型 (特にファミリー) 用のシンタックス シュガーはありませんがFunction*、同様の簡単なシンタックスが必要です。私が今持っている最善の方法は、asオペレーターを使用してグルーヴィーなクロージャーをスカラ型に強制することです。

List<String> list = ... // Scala list
list.map({ it.toUpperCase() } as Function1<String,String>)

as ...テールは実際のクロージャーよりも大きいため、毎回テールを含める必要はありません。

This questionは、パラメーターの型を指定しないように受信メソッドを変更することを提案していますが、それは制御できるグルーヴィーなメソッドである場合にのみ機能します。コンパイル済みの scala/java クラスを使用しています。

Groovy で物事を暗黙的に変換するためのさまざまな手段があることは承知していますが、独立してロードされる小さな分離された Groovy スクリプトが多数あります。ロードされたすべてのプラグインが最小限のセレモニーとインポートでこの暗黙的な変換を取得するように、このアーキテクチャに最適なメカニズムを理解するのに十分なほどグルーヴィーを知りません。私は約 50 以上のプラグインを持っているので、この scala/groovy 相互運用を合理化することは私にとって価値があります。

これは、groovy スクリプトをロードする方法の簡略化されたバージョンです (Pluginは私のタイプの 1 つです)。

// Created once
val currentClassLoader = this.getClass.getClassLoader
val groovyClassLoader = new GroovyClassLoader(currentClassLoader)

...

// Many plugins created this way
val pluginFile = new java.io.File("path/to/some/plugin/MyPlugin.groovy")
val plugin: Plugin = groovyClassLoader.parseClass(pluginFile).asInstanceOf[Plugin]

// Use it
val list = List(1,2,3)
val answer = plugin.process(list)

前もって感謝します!

-ローハン

4

1 に答える 1

0

Function1 scala が生成するバイトコードを確認したところ、これはインターフェイスですが、単一の抽象メソッドを持つインターフェイスではありませんでした。これは、SAM 変換には役に立たないことを意味します。Java 8 では、ラムダを使用して自動変換することはできません。AbstractFunction1 もチェックしましたが、抽象クラスですが、抽象メソッドがないため、Groovy のように拡張 SAM 変換には役に立ちません。

私が見る唯一の解決策は、変換を行う拡張モジュールを作成することです。

編集: scala-java8-compatが役立つかもしれません。Groovy 2.2.0 +の場合、開いているブロックのSAM変換も可能にする、scala FunctionNのjava8ラムダを許可することをターゲットにしています+

于 2015-05-20T16:01:04.783 に答える