24

いくつかの OpenJDK メーリングリスト エントリを読んだ後、Oracle の開発者は現在、クロージャの提案からさらに削除しているようです。これは、Java 言語の初期の設計ミスにより、Java クロージャの導入が複雑になっているためです。

Scala クロージャーが Java 8 で計画されているクロージャーよりもはるかに強力であることを考えると、たとえば、Scala からクロージャーを取得する Java メソッドを呼び出したり、Java でクロージャーを定義してそれを Scala 関数に渡したりすることが可能になるのでしょうか?

では、Java クロージャはバイトコードで Scala の対応するものと同じように表現されるのでしょうか、それとも別の方法で表現されるのでしょうか? Java/Scala クロージャー間の機能のギャップを埋めることは可能でしょうか?

4

3 に答える 3

15

ここに2つの利害関係者のグループがあると仮定するよりも複雑だと思います。Project Lambdaの人々は、ほとんどOracleの人々とは独立して働いているようで、ProjectLambdaの人々が間接的に見つけた何かを壁に投げかけることがあります。(もちろん、Scalaは3番目の利害関係者です。)

最新のProjectLambdaの提案は、関数型をすべて一緒に削除し、単一のastractメソッド( SAM型)を持つインターフェイスを実装するためのある種の凝った推論を作成することであるため、次のことを予測します。

  • Scalaクロージャを必要とするScalaコードの呼び出しは、特性の実装(および一般的な特性の実装)に完全に依存しFunction*ます-JavaコンパイラにSAM(Scalaランドにある)として表示されるかどうか、または非抽象メソッドもJVMには抽象的に見えます。(特性はインターフェースとして実装されているため、現在は抽象的であるように見えると思いますが、Scalaの実装についてはほとんど何も知りません。これは、相互運用性に対する大きなハードルになる可能性があります。)

    Javaジェネリックの複雑さ(特に、ジェネリックインターフェイスでInt/ int/ Integer、またはUnit/ Nothing/を表現する方法void)も複雑になる可能性があります。

  • Scala関数を使用してJavaSAMを実装することは、現在と何ら変わりはありませんimplicit。実装する特定のインターフェースの変換を作成する必要があります。

JVMが関数型を取得する場合(そしてOracleがその可能性を排除していないように思われる場合)、それはそれがどのように実装されているかに依存する可能性があります。それらが特定のインターフェースを実装するファーストクラスのオブジェクトである場合、互換性を保つためにScalaが行う必要があるのはFunction*、新しいインターフェースを実装することだけです。新しい種類のタイプがJVMに完全に実装されている場合、これは難しい可能性があります。Scala開発者は、現在のように魔法を使ってそれらをラップしArrayたり、作成implicit変換を作成したりできます。(新しい言語の概念は少し遠いようです。)

このすべての議論の結果の1つが、さまざまなJVM言語のすべてが、クロージャを表す標準的な方法に同意することです。これにより、Scala、Groovy、JRubyなどがすべてクロージャを前後に渡すことができます。手間を最小限に抑えます。

私にとってもっと興味深いのは、JavaコレクションAPIがラムダを使用できるようにする仮想拡張メソッドの提案です。これらの実装方法によっては、Scalaコードを変更するときに対処しなければならなかったバイナリ互換性の問題のいくつかを大幅に簡素化し、特性をより簡単かつ効率的に実装するのに役立つ場合があります。

Scala開発者の何人かが参加して意見を提供してくれることを願っていますが、Project LambdaリストでScalaについての議論を見たことがなく、Scala開発者として私に飛びついた参加者もいません。

于 2010-08-04T19:21:39.630 に答える
7

暗黙の変換がそのまま使用できるかどうかに関係なく暗黙の変換 を使用して、これを非常に簡単に実行できる可能性があります。 collection.JavaConversions

もちろん、これは明らかにそうではありません.Javaクロージャが実行時にJVMによって生成される型に変換される可能性があるためです.Neal Gafterのプレゼンテーションでこれらの行に沿って何かを言っているようです.

于 2010-06-15T17:25:40.377 に答える
2

注: 5 年後のSCALA 2.12.0-M3 (2015 年 10 月)には、次の拡張機能が含まれていました。

Scala 2.12 は、Java 8 と同じスタイルでクロージャーを発行します

ラムダごとに、コンパイラはラムダ本体を含むメソッドを生成します。
実行時に、このメソッドはLambdaMetaFactoryJDK によって提供される に引数として渡され、クロージャ オブジェクトが作成されます。

Scala 2.11 と比較すると、新しいスキームには、コンパイラがラムダごとに無名クラスを生成しないという利点があります。これにより、JAR ファイルが大幅に小さくなります。

于 2016-03-30T10:58:59.777 に答える