2017-09-06 3 views
4

私はScala 2.11を使用しています。私はのような機能を作成する場合:VarArgs A * vs Seq [A]関数のパラメータ

def func1 (a: Int*) : Int = a.reduce(_+_) 

私は大丈夫です

func1(1,2,3,4) 
// 10 
func1(Seq(1,2,3,4) : _*) 
//10 

を使用してそれを呼び出します。

しかし、私のような関数リテラルを定義しよう:

val func2:(Int*) => Int = _.reduce(_+_) 

私はというエラーを取得:

<console>:5: error: type mismatch; 
found : Int* => Int 
required: Seq[Int] => Int 
    lazy val $result = INSTANCE.`func2` 

は、なぜそれがない最初にかかわらず、後者の場合にはSeq[Int]をしたいがありません定義は同じですか?

reduceが最初に呼び出されるように、どのようにvarargsが渡されますか?

+1

[Scalaの関数オブジェクトの可変オブジェクトによるエラー?](https://stackoverflow.com/questions/8623126/error-with-varargs-for-function-objects-in-scala) – Suma

答えて

2

Scalaはメソッドと関数を区別します。 func1は、パラメータがrepeatedのメソッドであり、フードの下で単純なSeqに変更されています。一方、func2は関数であり、繰り返しのパラメータはそのコンテキストでは使用できません。

コンパイラが関数を期待しているが、代わりにメソッドが与えられている場合、コンパイラは関数を展開します。たとえば、メソッドdef(s: String) = sは、関数(s: String) => sに変換されます。私は、方法と機能の区別が非常に明確で非常に重要であるということを指摘しています。

私が提供したリンクには、関数宣言と定義があります。これは、実際には関数ではなくメソッドに関するものであるため、不器用な名前です。関数は、他のどのような値でもあり、例えば、コレクションに保持されるか、別の関数から返されます。メソッドはできません。

最終的なコメントと私はやっています:一般的な間違いをしないでください、 "defはメソッドです、valは関数です"と思ってください。関数はvalの代わりにdefを使用して定義することもできます。この場合でも関数の値ですが、宣言のポイントではなく使用時に評価されます。メソッドと関数を区別する最も良い方法は、パラメータを確認することです。def foo(someParameter: X): Yがメソッドです。関数は "(someParameter:X)"部分を持つことはできません。代わりに、関数は単なる値であり、そのタイプはX => Yである:私は意図的に(ヴァル-DEF間違いを犯してから読者を防ぐために)点を作るために、あまりにも機能するためdefを使用

// method 
def foo(x: X): Y = // some code that returns Y 

// function 
def foo: X => Y = (x: X) => // some code that returns Y 

valを使用して関数を定義する方が一般的です。

+0

あなたの区別方法と機能との間の関係は主観的である。あなたは仮定を裏付けるドキュメンテーションを提供できますか? Btw私はそれに同意しない:)あなたは2番目の 'foo'は"関数を返すメソッド "または"関数を返す関数 "になる可能性があります – pedromss

+0

ありがとうございます。 – philantrovert

+0

私は別の質問があります。あなたはvarargsが簡単な 'Seq'_にフードの下に置かれていると言います、なぜ' 'Seq(1,2,3)'を 'func1'に直接渡すことができないのですか? – philantrovert

関連する問題