数値を多用するコードの場合、次のシグネチャを使用して関数を記述しました。
def update( f: (Int,Int,Double) => Double ): Unit = {...}
ただし、Function3
特殊化されていないため、アプリケーションを適用するたびにf
、3つの引数と結果タイプがボックス化/ボックス化解除されます。
特別なアップデータークラスを使用できます。
trait Updater {
def apply( i: Int, j: Int, x: Double ): Double
}
def update( f: Updater ): Unit = {...}
しかし、呼び出しは面倒です(そしてJavaっぽい):
//with function
b.update( (i,j,_) => if( i==0 || j ==0 ) 1.0 else 0.5 )
//with updater
b.update( new Updater {
def apply( i: Int, j: Int, x: Double ) = if( i==0 || j ==0 ) 1.0 else 0.5
} )
ラムダ構文を使用しながら、ボクシング/アンボクシングを回避する方法はありますか?マクロが役立つことを望んでいましたが、解決策がわかりません。
編集:私はjavapでfunction3で生成されたバイトコードを分析しました。ボックス化されていないメソッドは、ジェネリックメソッド(以下を参照)に沿ってコンパイラーによって生成されます。箱から出されたものを直接呼び出す方法はありますか?
public final double apply(int, int, double);
Code:
0: ldc2_w #14; //double 100.0d
3: iload_2
4: i2d
5: dmul
6: iload_1
7: i2d
8: ddiv
9: dreturn
public final java.lang.Object apply(java.lang.Object, java.lang.Object, java.lang.Object);
Code:
0: aload_0
1: aload_1
2: invokestatic #31; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
5: aload_2
6: invokestatic #31; //Method scala/runtime/BoxesRunTime.unboxToInt:(Ljava/lang/Object;)I
9: aload_3
10: invokestatic #35; //Method scala/runtime/BoxesRunTime.unboxToDouble:(Ljava/lang/Object;)D
13: invokevirtual #37; //Method apply:(IID)D
16: invokestatic #41; //Method scala/runtime/BoxesRunTime.boxToDouble:(D)Ljava/lang/Double;
19: areturn