web-dev-qa-db-ja.com

Scalaのeta拡張とは何ですか?

私は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が行うことはそれだけですか?

22
Lifu Huang

定義といくつかの例は 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拡張が必要な​​シナリオは何ですか?

  1. 具体的に要求した場合(例:_someMethod __)。

  2. 関数型(またはScala 2.12)のSAM型)の値が期待されるメソッド(パラメーター付き)を使用する場合。例:.

    _def foo(f: Int => Int) = ???
    
    foo(someMethod)
    _
  3. それでおしまい。

Eta-expansionとプレースホルダー付きの無名関数(someMethod(_))を使用すると、型推論や暗黙的な操作などにより、動作が異なる場合があることに注意してください。

19
Alexey Romanov