web-dev-qa-db-ja.com

Scalaはメソッド定義で複数のパラメータを受け取ることができますか?

Javaには次の機能があります。

public void someMethod(int ... intArray) { // question: what is the equivalent to "..." 
    // do something with intArray
}

scalaで同じ機能を実現するにはどうすればよいですか?つまり、未定義の数のパラメーターをメソッドに渡しますか?

30
dankilman
def someMethod(values : Int*)

配列を与えます。可変引数パラメーターを最後の仮パラメーターとして配置します。

43
Joe

JavaおよびScalaには可変引数があり、どちらも最後のパラメーターに対してのみそれをサポートします。

 def varargTest(ints:Int*) { ints.foreach(println) }  

この記事 から、varargs引数に使用されるタイプに違いがあります:

  • javaの配列
  • ScalaのSeq(シーケンス):反復可能であり、コレクションforeach、map、filter、find、...などの多くのメソッドが使用可能です

「*」は0個以上の引数を表します。

注:パラメータ値がリストなどのシーケンスとしてすでに「パッケージ化」されている場合、失敗します。

# varargTest(List(1,2,3,4,5))  
# //--> error: type mismatch;  
# //-->  found   : List[Int]  
# //-->  required: Int  
# //-->        varargTest(List(1,2,3,4,5))  
# //--> 

しかし、これは成功します:

  varargTest(List(1,2,3):_*)  
  //--> 1  
  //--> 2  
  //--> 3  

'_'は、型推論のプレースホルダーショートカットです。 '_*'は、ここで '繰り返しタイプに適用されます。
Scala仕様 のセクション4.6.2は次のように述べています:

パラメータセクションの最後の値のパラメータには、末尾に「*”」を付けることができます。 (..., x:T *)
メソッド内のそのような繰り返されるパラメータのタイプは、シーケンスタイプscala.Seq[T]です。
パラメータが繰り返されるメソッドT*は、T型の可変数の引数を取ります。

 (T1, . . . , Tn,S*)U => (T1, . . . , Tn,S, . . . , S)U, 

このルールの唯一の例外は、最後の引数が_*型注釈を介してシーケンス引数であるとマークされている場合です。

 (e1, . . . , en,e0: _*) => (T1, . . . , Tn, scala.Seq[S]).

注bis:Javaの基本的な型消去に注意してください。

//--> error: double definition:
//--> method varargTest:(ints: Seq[Int])Unit and
//--> method varargTest:(ints: Int*)Unit at line 10
//--> have same type after erasure: (ints: Sequence)Unit
//-->   def varargTest(ints:Seq[Int]) { varargTest(ints: _*) }
49
VonC