web-dev-qa-db-ja.com

Scalaのメソッドと関数の違い

読んだScala Functionsの一部Scalaの別のツアー)。その投稿で彼は次のように述べました。

メソッドと関数は同じものではありません

しかし、彼はそれについて何も説明しませんでした。彼は何を言おうとしていたのですか?

242
Anantha Kumaran

メソッドと関数の大きな実際的な違いの1つは、returnの意味です。 returnはメソッドからのみ返されます。例えば:

scala> val f = () => { return "test" }
<console>:4: error: return outside method definition
       val f = () => { return "test" }
                       ^

メソッドで定義された関数から戻ると、ローカルではない戻り値が返されます。

scala> def f: String = {                 
     |    val g = () => { return "test" }
     | g()                               
     | "not this"
     | }
f: String

scala> f
res4: String = test

一方、ローカルメソッドから返されるのは、そのメソッドからのみ返されます。

scala> def f2: String = {         
     | def g(): String = { return "test" }
     | g()
     | "is this"
     | }
f2: String

scala> f2
res5: String = is this
65
Ben Lings

function引数のリストを使用して関数を呼び出して、結果を生成できます。関数には、パラメーターリスト、ボディ、および結果タイプがあります。クラス、トレイト、またはシングルトンオブジェクトのメンバーである関数は、methodsと呼ばれます。他の関数内で定義された関数は、ローカル関数と呼ばれます。結果タイプがUnitの関数は、プロシージャと呼ばれます。ソースコード内の匿名関数は、関数リテラルと呼ばれます。実行時に、関数リテラルは関数値と呼ばれるオブジェクトにインスタンス化されます。

Scala Second Editionでのプログラミング。MartinOdersky-Lex Spoon-Bill Venners

35
jamlhet

リストがあるとしましょう

scala> val x =List.range(10,20)
x: List[Int] = List(10, 11, 12, 13, 14, 15, 16, 17, 18, 19)

メソッドを定義する

scala> def m1(i:Int)=i+2
m1: (i: Int)Int

関数を定義する

scala> (i:Int)=>i+2
res0: Int => Int = <function1>

scala> x.map((x)=>x+2)
res2: List[Int] = List(12, 13, 14, 15, 16, 17, 18, 19, 20, 21)

引数を受け入れるメソッド

scala> m1(2)
res3: Int = 4

Valを使用した関数の定義

scala> val p =(i:Int)=>i+2
p: Int => Int = <function1>

関数への引数はオプションです

 scala> p(2)
    res4: Int = 4

scala> p
res5: Int => Int = <function1>

メソッドへの引数は必須です

scala> m1
<console>:9: error: missing arguments for method m1;
follow this method with `_' if you want to treat it as a partially applied function

以下を確認してください チュートリアル メソッドVs関数、変数としての関数の使用、関数を返す関数の作成を使用したdiffの他の例のような例で他の違いを渡すことを説明します

29
anish

関数はパラメーターのデフォルトをサポートしていません。メソッドは行います。メソッドから関数に変換すると、パラメーターのデフォルトが失われます。 (スカラ2.8.1)

12
eptx

ニースの記事があります ここ ここから私の説明のほとんどが取られます。私の理解に関する関数とメソッドの簡単な比較。それが役に立てば幸い:

関数:それらは基本的にオブジェクトです。より正確には、関数はapplyメソッドを持つオブジェクトです。したがって、オーバーヘッドのため、メソッドよりも少し遅くなります。呼び出されるオブジェクトに依存しないという意味では、静的メソッドに似ています。関数の簡単な例は、次のようになります。

val f1 = (x: Int) => x + x
f1(2)  // 4

上記の行は、object1 = object2のように、あるオブジェクトを別のオブジェクトに割り当てること以外は何もありません。実際、この例のobject2は匿名関数であり、そのために左側にオブジェクトの型があります。したがって、現在f1はオブジェクト(関数)です。無名関数は、実際にはFunction1 [Int、Int]のインスタンスです。これは、Int型の1つのパラメーターとInt型の戻り値を持つ関数を意味します。引数なしでf1を呼び出すと、匿名関数の署名が得られます(Int => Int =)

メソッド:これらはオブジェクトではなく、クラスのインスタンス、つまりオブジェクトに割り当てられます。 Javaのメソッドまたはc ++のメンバー関数とまったく同じです( Raffi Khatchadourian へのコメントで指摘されている この質問 )など。メソッドの例は次のようになります。

def m1(x: Int) = x + x
m1(2)  // 4

上記の行は、単純な値の割り当てではなく、メソッドの定義です。 2行目のように値2でこのメソッドを呼び出すと、xが2に置き換えられ、結果が計算され、出力として4が取得されます。ここでは、メソッドであり、入力値が必要なため、単にm1を書き込むだけでエラーが発生します。 _を使用すると、次のような関数にメソッドを割り当てることができます。

val f2 = m1 _  // Int => Int = <function1>
6
Mehran

これは素晴らしい post Rob Norrisによる違いを説明しています。ここはTL; DRです

Scalaのメソッドは値ではありませんが、関数は値です。 η-expansionを介してメソッドに委任する関数を作成できます(末尾のアンダースコアでトリガーされます)。

次の定義で:

a method is something defined with def and a value is something you can assign to a val

一言で言えば(ブログから抽出):

メソッドを定義すると、valに割り当てることができないことがわかります。

scala> def add1(n: Int): Int = n + 1
add1: (n: Int)Int

scala> val f = add1
<console>:8: error: missing arguments for method add1;
follow this method with `_' if you want to treat it as a partially applied function
       val f = add1

add1typeも注意してください。これは正常に見えません。 (n: Int)Int型の変数を宣言することはできません。メソッドは値ではありません。

ただし、η-expansion後置演算子(ηは「eta」と発音されます)を追加することにより、メソッドを関数値に変換できます。 fのタイプに注意してください。

scala> val f = add1 _
f: Int => Int = <function1>

scala> f(3)
res0: Int = 4

_の効果は、次と同等の処理を実行することです。メソッドに委任するFunction1インスタンスを作成します。

scala> val g = new Function1[Int, Int] { def apply(n: Int): Int = add1(n) }
g: Int => Int = <function1>

scala> g(3)
res18: Int = 4
2
Valy Dia