サーチ…


備考

Scalaにはファーストクラスの機能があります。

関数とメソッドの違い:

関数はScalaのメソッドではありません。関数は値であり、そのように割り当てられます。一方、 defdefを使用して作成された)メソッドは、クラス、特性、またはオブジェクトに属していなければなりません。

  • 関数は、コンパイル時に特性( Function1など)を拡張するクラスにコンパイルされ、実行時に値にインスタンス化されます。一方、メソッドは、そのクラス、特性、またはオブジェクトのメンバーであり、その外には存在しません。
  • メソッドを関数に変換することはできますが、関数をメソッドに変換することはできません。
  • メソッドは型パラメータ化を持つことができますが、関数は型パラメータ化できません。
  • メソッドはパラメータのデフォルト値を持つことができますが、関数はできません。

匿名関数

匿名関数は、定義されていて名前を割り当てられていない関数です。

以下は、2つの整数を取り、その合計を返す無名関数です。

(x: Int, y: Int) => x + y

結果の式をval代入することができます。

val sum = (x: Int, y: Int) => x + y

匿名関数は、主に他の関数の引数として使用されます。たとえば、コレクションのmap関数は、引数として別の関数を期待しています。

// Returns Seq("FOO", "BAR", "QUX")
Seq("Foo", "Bar", "Qux").map((x: String) => x.toUpperCase)

無名関数の引数の型は省略できます:型は自動的に推論されます

Seq("Foo", "Bar", "Qux").map((x) => x.toUpperCase)

引数が1つだけの場合、その引数の前後のカッコは省略できます。

Seq("Foo", "Bar", "Qux").map(x => x.toUpperCase)

下線は略語

引数の名前を必要としない、さらに短い構文があります。上記のスニペットは次のように記述できます:

Seq("Foo", "Bar", "Qux").map(_.toUpperCase)

_は無名関数の引数を位置的に表します。複数のパラメータを持つ無名関数では、 _が出現するたびに異なる引数が参照されます。たとえば、次の2つの式は等価です。

// Returns "FooBarQux" in both cases
Seq("Foo", "Bar", "Qux").reduce((s1, s2) => s1 + s2)
Seq("Foo", "Bar", "Qux").reduce(_ + _)

この短縮形を使用する場合、位置_によって表される引数は、1回だけ同じ順序で参照することができます。

パラメータなしの無名関数

パラメータを使用しない無名関数の値を作成するには、パラメータリストを空白のままにします。

val sayHello = () => println("hello")

組成

機能構成は、2つの機能を動作させ、単一の機能として見ることができる。関数f(x)と関数g(x)与えられたg(x) 、関数h(x) = f(g(x))と数学的に表現される。

関数がコンパイルされると、 Function1関連する型にコンパイルされます。 Scalaは、composition: andThencompose関連するFunction1実装の2つのメソッドを提供します。 composeメソッドは、上記の数学的定義に適合します。

val f: B => C = ...
val g: A => B = ...

val h: A => C = f compose g

andThenh(x) = g(f(x)) )は、より「DSLのような」感情を持っています:

val f: A => B = ...
val g: B => C = ...

val h: A => C = f andThen g

新しい無名関数が割り当てられ、 fg閉じられます。この関数は、両方の場合に新しい関数hに束縛されます。

def andThen(g: B => C): A => C = new (A => C){
  def apply(x: A) = g(self(x))
}

fまたはgいずれかが副作用で動作する場合、 hを呼び出すと、 fgすべての副作用がその順序で発生します。変更可能な状態の変更についても同様です。

部分関数との関係

trait PartialFunction[-A, +B] extends (A => B)

すべての単一引数PartialFunctionFunction1です。これは正式な数学的意味では直感的ではありませんが、オブジェクト指向の設計に適しています。このため、 Function1は、常にtrue isDefinedAtメソッドを提供する必要はありません。

部分関数(関数でもある)を定義するには、次の構文を使用します。

{ case i: Int => i + 1 } // or equivalently { case i: Int ⇒ i + 1 }

詳細については、 PartialFunctionsを見てください



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow