Como o Scala pode receber vários parâmetros em uma definição de método?
-
08-07-2019 - |
Pergunta
Java tem:
public void someMethod(int ... intArray) { // question: what is the equivalent to "..."
// do something with intArray
}
Como posso alcançar a mesma funcionalidade em Scala? Ou seja, passando um número indefinido de parâmetros para um método?
Solução
def someMethod(values : Int*)
Dá uma matriz. Coloque o parâmetro de argumento variável como o último parâmetro formal.
Outras dicas
Java e Scala têm varargs, e ambos suportam apenas para os últimos parâmetros.
def varargTest(ints:Int*) { ints.foreach(println) }
A partir de Este artigo, a diferença está no tipo usado para os argumentos de varargs:
- Array para Java
- SEQ (sequência) para scala: pode ser iterado e muitos métodos como coleções para cada um, mapa, filtrar, encontrar, ... estão disponíveis
O '*' significa 0 ou mais argumentos.
Nota: Se os valores dos parâmetros já estiverem "embalados" como uma sequência, como uma lista, ela falha:
# varargTest(List(1,2,3,4,5))
# //--> error: type mismatch;
# //--> found : List[Int]
# //--> required: Int
# //--> varargTest(List(1,2,3,4,5))
# //-->
Mas isso vai passar:
varargTest(List(1,2,3):_*)
//--> 1
//--> 2
//--> 3
'_
'É um atalho de espaço reservado para inferência de tipo. '_*
'é aqui aplicado a um tipo repetido.
Seção 4.6.2 de Especificação Scala menciona:
O último parâmetro de valor de uma seção de parâmetros pode ser sufixo por “
*”
, por exemplo(..., x:T *)
.
O tipo de parâmetro tão repetido dentro do método é então o tipo de sequênciascala.Seq[T]
.
Métodos com parâmetros repetidosT*
Pegue um número variável de argumentos do tipoT
.
(T1, . . . , Tn,S*)U => (T1, . . . , Tn,S, . . . , S)U,
A única exceção a esta regra é se o último argumento é marcado para ser um argumento de sequência por meio de um
_*
Anotação do tipo.
(e1, . . . , en,e0: _*) => (T1, . . . , Tn, scala.Seq[S]).
NOTA BIS: Cuidado com o apagamento do tipo subjacente de 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: _*) }