如何在Scala中实现像Int*,String*这样的变种?

Pla*_*ove 1 scala

可能重复:
Scala中可变长度参数列表的类型是什么?

我最近在参数列表上发现了这篇文章:https://stackoverflow.com/a/4684598/1287554,我发现它真的很有趣.

我也理解下面给出的用例:

def fn(x:Int*) = x.sum                    //> fn: (x: Int*)Int  
fn(1,2,3)                                 //> res0: Int = 6
Run Code Online (Sandbox Code Playgroud)

我看到的显而易见的解释是,它是以下代码的某种语法糖:

def fn(x:List[Int]) = x.sum               //> fn: (x: List[Int])Int
fn(List(1,2,3))                           //> res0: Int = 6
Run Code Online (Sandbox Code Playgroud)

但是我找不到任何关于它们的文档.有人能指出一些链接来解释这种类型的功能参数吗?此外,他们被称为参数列表或其他什么?也许我找不到任何东西的原因是因为我用错误的名字搜索?

Dan*_*ral 6

这些是可变长度参数列表(根据规范重复参数,正如Randall其答案中正确指出的那样),通常称为"varargs",即实现此类功能的K&R C库函数的名称.

对于Scala,在JVM级别上,arg: T*参数arg: Seq[T]通常作为a传递WrappedArray.

Java与语法具有相同的功能T... arg,始终将参数传递为Array[T].Scala识别Java varargs并且可以像Scala一样调用它们.

Scala varargs和Java varargs之间的一个重要区别是用于调用实现它们的方法的约定,而不是传递参数,而是包含它们的对象.在Java中,您只需传递一个数组:

public void m(String... args)

String[] list = new String[] { "a", "b", "c" };
m(list)
Run Code Online (Sandbox Code Playgroud)

在Scala中,您必须使用特殊语法来明确您的意思:

val list = Seq("a", "b", "c")
m(list: _*)
Run Code Online (Sandbox Code Playgroud)

另外值得注意的是,在模式匹配时你有一个converse运算符:

list match {
    case Seq(xs @ _*) => xs.size
    case _            => 0
}
Run Code Online (Sandbox Code Playgroud)