Mam następujący fragment kodu z tego pytania :
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!")
}
Wszystko w nim jest dość jasne, z wyjątkiem tego kawałka: child ++ newChild : _*
Co to robi?
Rozumiem, że istnieje Seq[Node]
powiązanie z innym Node
, a następnie? Co ma : _*
zrobić?
scala
pattern-matching
Amorfis
źródło
źródło
Odpowiedzi:
To „splats” 1 sekwencję.
Spójrz na podpis konstruktora
który nazywa się jako
ale tutaj jest tylko sekwencja, nie
child1
,child2
itp więc pozwala to sekwencja wynik zostać wykorzystane jako wejście do konstruktora.Szczęśliwego kodowania.
1 To nie ma uroczej nazwy w SLS, ale oto szczegóły. Ważną rzeczą do uzyskania jest to, że zmienia sposób, w jaki Scala wiąże argumenty z metodą z powtarzanymi parametrami (jak
Node*
wskazano powyżej)._*
Typ adnotacji jest pokryta „4.6.2 Powtarzające parametry” SLS.źródło
child ++ newChild
- sekwencja:
- type ascription, wskazówka, która pomaga kompilatorowi zrozumieć, jaki typ ma to wyrażenie_*
- symbol zastępczy akceptujący dowolną wartość + operator varargchild ++ newChild : _*
rozwija sięSeq[Node]
doNode*
(mówi kompilatorowi, że raczej pracujemy z varargs niż z sekwencją). Szczególnie przydatny w metodach, które mogą akceptować tylko varargs.źródło
Wszystkie powyższe odpowiedzi wyglądają świetnie, ale wystarczy próbka, aby to wyjaśnić. Oto on:
Teraz wiemy, co
:_*
należy powiedzieć kompilatorowi: rozpakuj ten argument i powiąż te elementy z parametrem vararg w wywołaniu funkcji, zamiast traktować x jako pojedynczy argument.Krótko mówiąc,
:_*
ma to na celu usunięcie niejednoznaczności podczas przekazywania argumentu do parametru vararg.źródło
Dla niektórych leniwych ludzi, takich jak ja, konwertuje Seq na varArgs!
źródło