Ответ 1
def someMethod(values : Int*)
Дает массив. Поместите параметр аргумента переменной в качестве последнего формального параметра.
Java имеет:
public void someMethod(int ... intArray) { // question: what is the equivalent to "..."
// do something with intArray
}
Как я могу достичь той же функциональности в Scala? То есть, передавая undefined количество параметров методу?
def someMethod(values : Int*)
Дает массив. Поместите параметр аргумента переменной в качестве последнего формального параметра.
И Java, и Scala имеют varargs, и оба поддерживают его только для последних параметров.
def varargTest(ints:Int*) { ints.foreach(println) }
Из в этой статье разница в типе, используемом для аргументов varargs:
"*" означает 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
'_
' является ярлыком-заполнителем для вывода типа.
'_*
' здесь применяется к повторному типу.
В разделе 4.6.2 Scala Спецификация упоминается:
Последний параметр параметра секции параметров может быть суффикс "
*"
, например.(..., 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: _*) }