實現與Scala編譯器有很大不同。的咖喱版本編譯成Java方法通過未討好的參數:
def f1(elem: Int, other: Int): Boolean = elem.==(other);
第二個版本是返回一個匿名函數(一個Function1
),所以它們的簽名是完全不同的方法。雖然他們往往可以互換Scala代碼中使用,有相當多的在第二個版本生成代碼:
def f2(elem: Int): Function1 = (new <$anon: Function1>(elem): Function1);
@SerialVersionUID(value = 0) final <synthetic> class anonfun$f2$1 extends scala.runtime.AbstractFunction1$mcZI$sp with Serializable {
final def apply(other: Int): Boolean = anonfun$f2$1.this.apply$mcZI$sp(other);
<specialized> def apply$mcZI$sp(other: Int): Boolean = anonfun$f2$1.this.elem$1.==(other);
final <bridge> <artifact> def apply(v1: Object): Object = scala.Boolean.box(anonfun$f2$1.this.apply(scala.Int.unbox(v1)));
<synthetic> <paramaccessor> private[this] val elem$1: Int = _;
def <init>(elem$1: Int): <$anon: Function1> = {
anonfun$f2$1.this.elem$1 = elem$1;
anonfun$f2$1.super.<init>();
()
}
}
我只會使用情況下,第二個版本考慮我在那裏明確地找工作與Function1
對象。不過,我個人傾向於使用咖喱版,因爲您仍然可以通過部分應用第一個獲得Function1
。咖喱版本功能同樣強大,但當您不需要它們時不會創建對象Function1
。
scala> f1(1) _
res1: Int => Boolean = <function1>
謝謝你的答案。你如何從scala生成java代碼?還有,會像'val f3 =(_:Int)==(_:Int); f3.curried'遭受你用'f2'指出的同樣的問題? –
您無法真正從Scala生成清晰的Java字節碼(但可以生成字節碼)。我使用'-Xprint:jvm'在我的答案中生成了代碼,這是Scala編譯器的最後階段之一。 'f3.curried'會創建_two_匿名函數而不是一個,所以它會產生比'f2'多的字節碼。 –