`:_*`(冒号下划线星)在 Scala 中有什么作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6051302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does `:_*` (colon underscore star) do in Scala?
提问by amorfis
I have the following piece of code from this question:
我从这个问题中有以下一段代码:
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!")
}
Everything in it is pretty clear, except this piece: child ++ newChild : _*
里面的一切都很清楚,除了这一段: child ++ newChild : _*
What does it do?
它有什么作用?
I understand there is Seq[Node]concatenated with another Node, and then? What does : _*do?
我知道有Seq[Node]与另一个连接Node,然后呢?有什么作用: _*?
采纳答案by amorfis
It "splats"1the sequence.
它“splats” 1序列。
Look at the constructor signature
看构造函数签名
new Elem(prefix: String, label: String, attributes: MetaData, scope: NamespaceBinding,
child: Node*)
which is called as
这被称为
new Elem(prefix, label, attributes, scope,
child1, child2, ... childN)
but here there is only a sequence, not child1, child2, etc. so this allows the result sequence to be used as the input to the constructor.
但这里只有一个序列,而不是child1、child2等,因此这允许将结果序列用作构造函数的输入。
Happy coding.
快乐编码。
1This doesn't have a cutesy-name in the SLS, but here are the details. The important thing to get is that it changes how Scala binds the arguments to the method with repeated parameters (as denoted with Node*above).
1这在 SLS 中没有一个可爱的名字,但这里有详细信息。重要的是它改变了 Scala 将参数绑定到具有重复参数的方法的方式(如上所示Node*)。
The _*type annotationis covered in "4.6.2 Repeated Parameters" of the SLS.
该_*类型的注释是包括在SLS的“4.6.2重复参数”。
The last value parameter of a parameter section may be suf?xed by “*”, e.g. (..., x:T *). The type of such a repeated parameter inside the method is then the sequence type scala.Seq[T]. Methods with repeated parameters T * take a variable number of arguments of type T . That is, if a method m with type (p1 : T1, . . . , pn : Tn,ps : S*)U is applied to arguments (e1, . . . , ek) where k >= n, then m is taken in that application to have type (p1 : T1, . . . , pn : Tn,ps : S, . . . , ps0S)U, with k ? n occurrences of type S where any parameter names beyond ps are fresh. The only exception to this rule is if the last argument is marked to be a sequence argument via a _* type annotation. If m above is applied to arguments (e1, . . . , en,e0 : _*), then the type of m in that application is taken to be (p1 : T1, . . . , pn : Tn,ps :scala.Seq[S])
参数部分的最后一个值参数可以带有“*”后缀,例如 (..., x:T *)。方法中这种重复参数的类型就是序列类型 scala.Seq[T]。具有重复参数 T * 的方法采用可变数量的 T 类型参数。也就是说,如果将类型为 (p1 : T1, . . , pn : Tn,ps : S*)U 的方法 m 应用于参数 (e1, . . . , ek) 其中 k >= n,则 m 为在该应用程序中采用类型 (p1 : T1, . . , pn : Tn,ps : S, . . , ps0S)U,其中 k ? 出现 n 次 S 类型,其中超出 ps 的任何参数名称都是新的。此规则的唯一例外是如果最后一个参数通过 _* 类型注释标记为序列参数。如果上面的 m 应用于参数 (e1, . . , en,e0 : _*),则该应用程序中 m 的类型被认为是 (p1 : T1, . . , pn : Tn,ps :scala .Seq[S])
回答by Vasil Remeniuk
child ++ newChild- sequence:- type ascription, a hint that helps compiler to understand, what type does that expression have_*- placeholder accepting any value + vararg operator
child ++ newChild- 顺序:- 类型归属,帮助编译器理解该表达式具有什么类型的提示_*- 占位符接受任何值 + 可变参数运算符
child ++ newChild : _*expands Seq[Node]to Node*(tells the compiler that we're rather working with a varargs, than a sequence). Particularly useful for the methods that can accept only varargs.
child ++ newChild : _*扩展Seq[Node]为Node*(告诉编译器我们更喜欢使用可变参数而不是序列)。对于只能接受可变参数的方法特别有用。
回答by Keith
All the above answer looks great, but just need a sample to explain this . Here it is :
以上所有答案看起来都很棒,但只需要一个示例来解释这一点。这里是 :
val x : Seq[Seq[Int]] = Seq(Seq(1),Seq(2))
def f(arg: Seq[Any]*) : Int = {
arg.length
}
f(x) //1 as x is taken as single arg
f(x:_*) // 2 as x is "unpacked" as a Seq[Any]*
So now we know what :_*do is to tell compiler : please unpack this argument and bind those elements to the vararg parameter in function call rather than take the x as a single argument .
所以现在我们知道做:_*什么是告诉编译器:请解压这个参数并将这些元素绑定到函数调用中的 vararg 参数,而不是将 x 作为单个参数。
So in a nutshell, the :_*is to remove ambiguity when pass argument to vararg parameter.
所以简而言之,:_*就是在将参数传递给 vararg 参数时消除歧义。
回答by mani_nz
For some of the lazy folks like me, it just converts a Seq to varArgs!
对于像我这样的懒人,它只是将 Seq 转换为 varArgs!

