Eu tenho o seguinte pedaço de código desta pergunta :
def addChild(n: Node, newChild: Node) = n match {
case Elem(prefix, label, attribs, scope, child @ _*) => Elem(prefix, label, attribs, scope, child ++ newChild : _*)
case _ => error("Can only add children to elements!")
}
Tudo está bem claro, exceto esta peça: child ++ newChild : _*
O que isso faz?
Eu entendo que é Seq[Node]
concatenado com outro Node
, e então? O que : _*
faz?
scala
pattern-matching
amorfis
fonte
fonte
Respostas:
Ele "divide" 1 a sequência.
Veja a assinatura do construtor
que é chamado como
mas aqui há apenas uma sequência, não
child1
,child2
etc., portanto, isso permite que a sequência de resultados seja usada como entrada para o construtor.Feliz codificação.
1 Isso não tem um nome atraente no SLS, mas aqui estão os detalhes. O importante a ser obtido é que ele altera como o Scala vincula os argumentos ao método com parâmetros repetidos (conforme indicado
Node*
acima).A
_*
anotação de tipo é abordada em "4.6.2 Parâmetros repetidos" do SLS.fonte
child ++ newChild
- seqüência:
- atribuição de tipo, uma dica que ajuda o compilador a entender, que tipo tem essa expressão_*
- espaço reservado que aceita qualquer valor + operador varargchild ++ newChild : _*
expandeSeq[Node]
paraNode*
(informa ao compilador que estamos trabalhando com um varargs, em vez de uma sequência). Particularmente útil para os métodos que podem aceitar apenas varargs.fonte
Toda a resposta acima parece ótima, mas só precisamos de uma amostra para explicar isso. Aqui está :
Então agora sabemos o que
:_*
fazer é dizer ao compilador: descompacte esse argumento e vincule esses elementos ao parâmetro vararg na chamada de função, em vez de considerar x como um único argumento.Portanto, resumindo,
:_*
é remover a ambiguidade quando passar o argumento para o parâmetro vararg.fonte
Para algumas pessoas preguiçosas como eu, apenas converte um Seq em varArgs!
fonte