Java has:
public void someMethod(int ... intArray) { // question: what is the equivalent to "..."
// do something with intArray
}
how can I achieve the same functionality in Scala? That is, passing an undefined number of parameters to a method?
Both Java and Scala have varargs, and both only support it for the last parameters.
def varargTest(ints:Int*) { ints.foreach(println) }
From this article, the difference is in the type used for the varargs arguments:
The '*' stands for 0 or more arguments.
Note: if the parameter values are already "packaged" as a sequence, such as a list, it fails:
# varargTest(List(1,2,3,4,5))
# //--> error: type mismatch;
# //--> found : List[Int]
# //--> required: Int
# //--> varargTest(List(1,2,3,4,5))
# //-->
But this will pass:
varargTest(List(1,2,3):_*)
//--> 1
//--> 2
//--> 3
'_
' is a placeholder shortcut for type inference.
'_*
' is here applyied to a 'repeated type.
Section 4.6.2 of Scala Specification mentions:
The last value parameter of a parameter section may be suffixed by “
*”
, e.g.(..., x:T *)
.
The type of such a repeated parameter inside the method is then the sequence typescala.Seq[T]
.
Methods with repeated parametersT*
take a variable number of arguments of typeT
.
(T1, . . . , Tn,S*)U => (T1, . . . , Tn,S, . . . , S)U,
The only exception to this rule is if the last argument is marked to be a sequence argument via a
_*
type annotation.
(e1, . . . , en,e0: _*) => (T1, . . . , Tn, scala.Seq[S]).
Note bis: beware of the underlying type erasure of 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: _*) }