2

いくつかのコードを調べて、関数に出くわしました

def sum(): Function2[Double, Double, Double] = 
  new Function2[Double, Double, Double] {
    def apply(t1: Double, t2: Double): Double = t1 + t2;
  }

これは、はるかに単純な宣言とどう違うのですか?

def sum(): Function2[Double, Double, Double] = _ + _

前者のアプローチを使用する利点はありますか?

4

1 に答える 1

2

可読性

詳細バージョンは、開発者にとって非常に明確ですJava。これは、Java の無名クラスのように見えます。したがって、ラムダの説明に使用できます。これが冗長バージョンの唯一の利点です。

REPL サポート

REPL には少し違いがありますが、あまり役に立ちません。

scala> new Function2[Double, Double, Double] {
     |   def apply(t1: Double, t2: Double): Double = t1 + t2;
     | }
res0: java.lang.Object with (Double, Double) => Double = <function2>

scala> val sum: (Double, Double) => Double = _ + _
sum: (Double, Double) => Double = <function2>

バイトコードサイズ

特性に関してjvm は、インターフェースです。トレイト コンパイラに基づいてクラスを作成すると、トレイトのコンパニオン オブジェクトからの実装の単純な呼び出しでメソッドが生成されます。

FunctionN最大 2 つのパラメーターがspecializedon IntLongおよびDoubleパラメーターである特性、結果の型パラメーターはさらに on UnitFloatおよびに特化されていBooleanます。これは、54 個の追加メソッド ( のような名前) を取得することを意味しFunction2ます。applyapply$mcZDD$sp

ラムダ バージョンでは、抽象クラスを使用していますscala.runtime.AbstractFunction2。すべてのメソッドは、このクラスで生成されます。必要なものだけをオーバーライドします。ClassName$anonfun$1.classlambda( )のクラスファイルのサイズは1012 バイトです。1kB未満。

new Function2すべてのメソッドが匿名クラスで生成される場合。匿名クラス ( ClassName$anon$1.class) のクラス ファイル サイズは約20 kBです。

for Function3(特殊化されていない) の違いはそれほど大きくありません: 1.1kBvs1.7kBですがFunctionN、引数が 0 ~ 2 のものが最も一般的なラムダです。AbstractFunctionNバイトコードがなければサイズが巨大になります。

于 2013-06-25T18:35:37.287 に答える