私はScalaを初めて使用します。 「etaexpansion」という言葉を聞いたばかりで、メソッドを関数オブジェクトに展開することを意味することを大まかに知っています。しかし、SOには、体系的に紹介しているリソースはほとんどありません。
Scalaでeta拡張がどのように機能するのか興味があります。 eta拡張が必要なシナリオは何ですか?そして、どのようにeta ExpansionがScalaに実装されていますか?
私はこのような場合にそれを大まかに知っています:
def someMethod(x: Int): Int = x * x
someMethod _
は、おおまかに次のような新しい関数オブジェクトに変換されます。
new Function1[Int, Int] {
def apply(x: Int): Int = x * x
}
Scalaが行うことはそれだけですか?
定義といくつかの例は http://scala-lang.org/files/archive/spec/2.11/06-expressions.html#method-values にあります。
_
someMethod _
_は、おおまかに次のような新しい関数オブジェクトに変換されます。
完全ではありません:実際には
_new Function1[Int, Int] {
def apply(x: Int): Int = someMethod(x)
}
_
違いは重要です。 someMethod
がどこかでオーバーライドされた場合。
Scalaが行うことはそれだけですか?
また、メソッドが複数のパラメーターリスト(関数を返す関数を取得する)または名前によるパラメーターを受け取る場合に何が起こるかを考慮する必要があります。
Eta拡張が必要なシナリオは何ですか?
具体的に要求した場合(例:_someMethod _
_)。
関数型(またはScala 2.12)のSAM型)の値が期待されるメソッド(パラメーター付き)を使用する場合。例:.
_def foo(f: Int => Int) = ???
foo(someMethod)
_
それでおしまい。
Eta-expansionとプレースホルダー付きの無名関数(someMethod(_)
)を使用すると、型推論や暗黙的な操作などにより、動作が異なる場合があることに注意してください。