У меня есть следующий кусок кода из этого вопроса :
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!")
}
Все в нем довольно ясно, кроме этой части: child ++ newChild : _*
Что оно делает?
Я так понимаю, что это связано Seq[Node]
с другим Node
, а потом? Что делает : _*
?
scala
pattern-matching
amorfis
источник
источник
Ответы:
Он "разбрызгивает" 1 последовательность.
Посмотрите на подпись конструктора
который называется как
но здесь есть только последовательность, а не
child1
,child2
и т. д., так что это позволяет использовать результирующую последовательность в качестве входных данных для конструктора.Удачного кодирования.
1 В SLS этого имени нет, но вот подробности. Важно то, что он меняет то, как Scala привязывает аргументы к методу с повторяющимися параметрами (как
Node*
указано выше)._*
Тип аннотации покрыта «4.6.2 Повторные параметры» СЛС.источник
child ++ newChild
- последовательность:
- тип ascription, подсказка, которая помогает компилятору понять, какой тип имеет это выражение_*
- заполнитель, принимающий любое значение + оператор varargchild ++ newChild : _*
расширяетсяSeq[Node]
доNode*
(говорит компилятору, что мы скорее работаем с varargs, чем с последовательностью). Особенно полезно для методов, которые могут принимать только varargs.источник
Все вышеприведенные ответы выглядят великолепно, но просто нужен образец, чтобы объяснить это. Вот :
Итак, теперь мы знаем, что
:_*
нужно сказать компилятору: пожалуйста, распакуйте этот аргумент и свяжите эти элементы с параметром vararg в вызове функции, а не принимайте x в качестве единственного аргумента.Итак, в двух словах,
:_*
это устранение неоднозначности при передаче аргумента параметру vararg.источник
Для некоторых ленивых, таких как я, он просто конвертирует Seq в varArgs!
источник