2

このコードを仮定します:

  def main(args: Array[String]) {
    val func = (x: String, y :String) => x + ", " + y
    println(myFunc(func))
  }

  def myFunc(f: (String, String) => String) = {
    f("Hey","how are you?")
  }

このコードの 2 行目は、コンパイラによって次のように置き換えられます。

val func = new Function2[String, String, String] {
             def apply(x: String, y: String): String = x + ", " + y
           } 

署名が示すように、この場合の型は型funcにも対応していると推測できます。と同じ型であることを意味します。(String, String) => String)myFuncFunction2[String, String, String](String, String) => String

なぜ違う表記?new ((String, String) => String)なぜ Scala コンパイラは関数リテラルをある種の概念的なものに変換しなかったのFunction2[String, String, String]ですか? またはその逆。

1 つの説明は、クラス名を次のようにマルチパートにすることはできないということです(T1, T2) => R。しかし、結局のところ、なぜでしょうか?

4

1 に答える 1

6

Scala コンパイラが関数リテラルをある種の概念的なものに変換しなかった理由:new (String, String) => String

Scala は JVM バイトコードにコンパイルされることを思い出してください。JVM には「概念的new (String, String) => String」というものはありません。オブジェクトとメソッドしかありません (少なくとも Java 8 まで)。Java 言語では、Guava と Apache Commons で退屈なCallable<T>RunnableまたはさまざまなFunction抽象化を使用する必要があります。それを回避する方法はありません。その観点からすると、Scala は基本的に、無名FunctionX[...]クラスに構文糖衣を追加することによって Java ボイラープレートを隠します。

これは、関数が期待される場所 (いわゆるeta 展開)でメソッドを使用するときに、Scala コンパイラが非常に多くの操作を行わなければならない理由の 1 つでもあります。

于 2012-12-05T18:26:33.300 に答える