3

Scala のメソッドと関数の違いに関する質問と、メソッドと関数の違いに関する多くの記事を読みました。「メソッド」は、クラス、トレイト、またはオブジェクトのメソッドとして定義された単なる「名前付き関数」であると感じました。「関数」は、それらの記事の「無名関数」または「関数リテラル」または「関数オブジェクト」のようなものを表します。証拠は本 Programming in Scala http://www.artima.com/shop/programming_in_scala_2ed、141 ページ、セクション 8.1 にあります。「関数を定義する最も一般的な方法は、オブジェクトのメンバーとしてです。関数はメソッドと呼ばれます。」

しかし、Scala 言語リファレンスhttp://www.scala-lang.org/docu/files/ScalaReference.pdfを確認したところ、名前付きメソッドのような概念があります。91 ページのセクション 6.20 戻り式: 「戻り式 return e は、囲んでいる名前付きメソッドまたは関数の本体内で発生する必要があります。」同じページや他の場所でも、「名前付き関数」という用語を見つけることができます。

私の質問は、Scala では、メソッド、名前付きメソッド、名前付き関数が同じ概念を参照しているのかということです。名前付き関数の定義はどこで取得しますか?

codeList(1, 2).map(_ + 1)では、元の式_ + 1は名前付きメソッドであり、メソッドは関数に変換されます。匿名関数、関数オブジェクト、名前付き関数の種類は何ですか?

私の理解では、Scala には 2 種類の関数しかありません。メソッドである名前付き関数です。関数リテラルである無名関数。関数リテラルは、Scala の純粋なオブジェクト指向の世界で使用されるように、トレイト FunctionN の関数オブジェクトにコンパイルされます。

しかし、上記のコードのような通常の名前付き関数/メソッド_ + 1の場合、なぜ Scala はそれを別の関数オブジェクトに変換するのでしょうか?

4

2 に答える 2

7

リンクされた質問への回答はこれをかなりうまくカバーしていますが、特定のクエリに対処するために:

  • defメソッド=>キーワードで定義するもの
  • 名前付きメソッド=>同じ、すべてのメソッドには名前があります
  • 名前付き関数=>値に割り当てられた、またはメソッドから変換された関数。匿名関数とは対照的です。

メソッドと関数の違いは、Javaのintプリミティブとボックス化されたものの違いにいくぶん似ています。Integer

一般的な議論では、両方が「整数」であると説明されるのを聞くのが一般的です。これは通常問題ではありませんが、区別が関係する場合は常に正確になるように注意する必要があります。

同様に、プリミティブをボックス化するのと同じように、プログラムが要求すると、メソッドは自動的に関数(したがってオブジェクト)に変換されます。したがって、メソッドを関数として参照することは完全に間違っているわけではありません。

アップデート

それで、それはどのように機能しますか?

たとえば、引数としてメソッドを渡そうとするとList[A].map、コンパイラは、を派生させる内部クラス(合成名を使用)とFunction1[A,B]apply最初に指定したメソッドに委任するメソッドを生成します。このインスタンスは、実際の引数として渡されます。

于 2011-09-08T06:45:57.867 に答える
7

言語レベルでは、2 つの概念しかありません。

  • メソッドは、Scala の基本的な構成要素です。メソッドには常に名前が付けられます。メソッドはクラスまたはトレイトに存在します。メソッドは JVM 固有の構造であるため、Scala と Java の両方で同じです。Scala のメソッドには (関数とは異なり) 特別な機能がある場合があります: 型パラメーターで抽象化できる、引数にデフォルト値を持たせたり、暗黙的にしたりできます。

  • 関数オブジェクトFunction1は、関数特性 ( 、Function2、 ...)の単なるインスタンスです。apply関数オブジェクトのメソッドが呼び出されると、関数が評価されます。名前のない「匿名」関数 (別名、「関数リテラル」) を定義するための特別な構文があります。関数は単なる値なので、名前を付けることができます (例: val f: (Int => Int) = (x => x))。タイプA => Bは の省略形ですFunction1[A, B]

リンクされた SO の質問では、一部の参照 (Scala 仕様など) が「関数」という言葉を不正確に使用して、「メソッド」または「関数オブジェクト」のいずれかを意味することが言及されています。その理由の一部は、コンテキストに応じて、メソッドが関数オブジェクトに自動的に変換される可能性があるためだと思います。ただし、逆の変換は意味がないことに注意してください。メソッドは、独自の独立した存在を持つヒープ上に存在するファーストクラスの値ではありません。むしろ、メソッドはそれが定義されているクラスに密接に関連しています。

于 2011-09-08T06:40:52.447 に答える