Param:_* 在 Scala 中是什么意思?

作为 Scala 的新手(2.9.1) ,我有一个 List[Event],并希望将它复制到一个 Queue[Event]中,但是下面的语法生成了一个 Queue[List[Event]]:

val eventQueue = Queue(events)

由于某种原因,以下作品:

val eventQueue = Queue(events : _*)

但我想知道它是做什么的,为什么会有效?我已经看过 Queue.apply函数的签名:

def apply[A](elems: A*)

我明白为什么第一次没成功但第二次的意义是什么?在这种情况下,什么是 :,什么是 _*,为什么 apply函数不能只取 Iterable[A]

48761 次浏览

这是一种特殊的表示法,它告诉编译器将每个元素作为自己的参数传递,而不是将所有元素作为单个参数传递。参见 给你

它是一个指示 序列参数序列参数的类型注释,在语言规范“重复参数”第4.6.2节中作为一般规则的“异常”被提及。

当一个函数接受数量可变的参数时,它是有用的,例如一个函数,比如 def sum(args: Int*),它可以作为 sum(1)sum(1,2)等调用。如果您有一个像 xs = List(1,2,3)这样的列表,那么您不能传递 xs本身,因为它是 List而不是 Int,但是您可以使用 sum(xs: _*)传递它的元素。

a: A是类型归属; 请参见 在 Scala 中使用类型属性的目的是什么?

: _* is a special instance of type ascription which tells the compiler to treat a single argument of a sequence type as a variable argument sequence, i.e. varargs.

使用具有一个序列或可迭代元素的 Queue.apply创建一个 Queue是完全有效的,所以当您给出一个 Iterable[A]时就会发生这种情况。

对于 Python 的朋友们:

Scala's _* operator is more or less the equivalent of Python's *-接线员.


例子

Converting the scala example from the 链接 provided by Luigi Plinge:

def echo(args: String*) =
for (arg <- args) println(arg)


val arr = Array("What's", "up", "doc?")
echo(arr: _*)

to Python would look like:

def echo(*args):
for arg in args:
print "%s" % arg


arr = ["What's", "up", "doc?"]
echo(*arr)

and both give the following output:

What's
起来
医生?


区别: 解包位置参数

Python 的 *操作符还可以解压缩固定值函数的位置参数/参数:

def multiply (x, y):
return x * y


operands = (2, 4)
multiply(*operands)

8

用 Scala 做同样的事情:

def multiply(x:Int, y:Int) = {
x * y;
}


val operands = (2, 4)
multiply (operands : _*)

将会失败:

没有足够的参数进行方法相乘: (x: Int,y: Int)。
未指定的值参数 y。

但 Scala 也有可能达到同样的效果:

def multiply(x:Int, y:Int) = {
x*y;
}


val operands = (2, 4)
multiply _ tupled operands

According to Lorrin Nelson this is how it works:

第一部分 f _ 是部分应用的函数的语法,其中没有指定任何参数。这是一种获取函数对象的机制。元组返回一个新的函数,该函数取一个单一的元组。

延伸阅读: