読んだScala Functions(の一部Scalaの別のツアー)。その投稿で彼は次のように述べました。
メソッドと関数は同じものではありません
しかし、彼はそれについて何も説明しませんでした。彼は何を言おうとしていたのですか?
メソッドと関数の大きな実際的な違いの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
function引数のリストを使用して関数を呼び出して、結果を生成できます。関数には、パラメーターリスト、ボディ、および結果タイプがあります。クラス、トレイト、またはシングルトンオブジェクトのメンバーである関数は、methodsと呼ばれます。他の関数内で定義された関数は、ローカル関数と呼ばれます。結果タイプがUnitの関数は、プロシージャと呼ばれます。ソースコード内の匿名関数は、関数リテラルと呼ばれます。実行時に、関数リテラルは関数値と呼ばれるオブジェクトにインスタンス化されます。
Scala Second Editionでのプログラミング。MartinOdersky-Lex Spoon-Bill Venners
リストがあるとしましょう
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の他の例のような例で他の違いを渡すことを説明します
関数はパラメーターのデフォルトをサポートしていません。メソッドは行います。メソッドから関数に変換すると、パラメーターのデフォルトが失われます。 (スカラ2.8.1)
ニースの記事があります ここ ここから私の説明のほとんどが取られます。私の理解に関する関数とメソッドの簡単な比較。それが役に立てば幸い:
関数:それらは基本的にオブジェクトです。より正確には、関数は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>
これは素晴らしい 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
add1
のtypeも注意してください。これは正常に見えません。 (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