什么`:_ *`(冒号下划线明星)在斯卡拉?
我有这样一个问题的代码:
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 [节点]连接到另一个节点,然后呢? 什么: _*
做什么?
提前致谢
它“splats” 1序列。
看看构造函数签名
new Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding, child: Node*)
这被称为
new Elem(prefix, label, attributes, scope, child1, child2, ... childN)
但是这里只有一个序列,而不是child1
, child2
等,所以这允许结果序列被用作构造函数的输入。
快乐的编码。
1这在SLS中没有可爱的名字,但是这里是细节。 重要的是,它改变了Scala如何用重复的参数来绑定参数(如上面的Node*
所示)。
SLS的“4.6.2重复参数”中涵盖了_*
类型的注释 。
参数段的最后一个值参数可以用“*”来表示,例如(…,x:T *)。 方法内部重复参数的类型是序列类型scala.Seq [T]。 重复参数T *的方法采用可变数量的T型参数。 也就是说,如果将类型(p1:T1,…,pn:Tn,ps:S *)U的方法m应用于其中k> = n的自变量(e1,…,ek),则m是(p1:T1,…,pn:Tn,ps:S,…,ps0S)U,其中k个出现的类型S,其中任何超出ps的参数名都是新鲜的。 这个规则的唯一例外是如果最后一个参数被标记为通过_ *类型注释的序列参数。 如果将上面的m应用于参数(e1,…,en,e0:_ *),那么该应用程序中m的类型取为(p1:T1,…,pn:Tn,ps:scala .SEQ [S])
-
child ++ newChild
– 序列 -
:
– 类型归属,帮助编译器理解的提示,该表达式具有什么类型 -
_*
– 占位符接受任何值+可变运算符
child ++ newChild : _*
将Seq[Node]
扩展为Node*
(告诉编译器,我们宁愿使用可变参数,而不是序列)。 对于只能接受可变参数的方法特别有用。