少年、それは微妙なものですが、私が知る限り、それはScalaの仕様に完全に準拠しています。仕様のバージョン2.9から引用します。
あなたの最初の例のために:あなたが正しく言うように、あなたはメソッド値(§6.7)の特別な場合を通してeta拡張を見ています:
The expression e _ is well-formed if e is of method type or if e is a call-by-name parameter. If e is a method with parameters, e _ represents e converted to a function type by eta expansion.
eta展開のアルゴリズムは、§6.26.5に記載されています。これに従って、式を次のように置き換えることができますnew Foo().x1 _
。
{
val x1 = new Foo();
(y1: Int) => x1.(y1);
}
これは、eta展開が使用されている場合、変換が行われる時点ですべてのサブ式が評価され(「最大サブ式」というフレーズの意味を正しく理解している場合)、最終的な式が作成であることを意味します。匿名関数の。
2番目の例では、これらの余分な括弧は、コンパイラーが§6.23(具体的には「無名関数のプレースホルダー構文」)を調べて、無名関数を直接作成することを意味します。
An expression (of syntactic category Expr) may contain embedded underscore symbols _ at places where identifiers are legal. Such an expression represents an anonymous function where subsequent occurrences of underscores denote successive parameters.
その場合、そのセクションのアルゴリズムに従うと、式は次のようになります。
(x1: Int) => new Foo().foo(x1)
違いは微妙で、@ Antorasによって非常によく説明されているように、実際には副作用のあるコードが存在する場合にのみ表示されます。
名前による呼び出しコードブロックを含むケースのバグ修正が進行中であることに注意してください(たとえば、この質問、このバグ、およびこのバグを参照してください)。
追記:どちらの場合も、無名関数(x1:Int) => toto
はに拡張されます
new scala.Function1[Int, Int] {
def apply(x1: Int): Int = toto
}