Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
像Int*、String*这样的varargs是如何在Scala中实现的?_Scala - Fatal编程技术网

像Int*、String*这样的varargs是如何在Scala中实现的?

像Int*、String*这样的varargs是如何在Scala中实现的?,scala,Scala,可能重复: 我最近在参数列表上看到了这篇文章:我觉得它非常有趣 我也理解下面给出的用例: def fn(x:Int*) = x.sum //> fn: (x: Int*)Int fn(1,2,3) //> res0: Int = 6 我看到的一个明显的解释是,它是以下代码的某种语法糖: def fn(x:List[Int]) = x.sum //&

可能重复:

我最近在参数列表上看到了这篇文章:我觉得它非常有趣

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

def fn(x:Int*) = x.sum                    //> fn: (x: Int*)Int  
fn(1,2,3)                                 //> res0: Int = 6
我看到的一个明显的解释是,它是以下代码的某种语法糖:

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

但是我找不到关于它们的任何文档。有人能给我指一些解释这种函数参数的链接吗?还有,它们被称为参数列表还是其他什么?可能我找不到任何东西的原因是因为我使用了错误的名称进行搜索?

这些是可变长度的参数列表(根据规范,如中正确指出的),通常称为“varargs”,是实现此类功能的K&R C库函数的名称

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

Java,它与语法
T有相同的东西。。。arg
,始终以数组[T]的形式传递参数。Scala可以识别Java变量,并可以像Scala一样调用它们

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

public void m(String... args)

String[] list = new String[] { "a", "b", "c" };
m(list)
而在Scala中,您必须使用特殊的语法来明确您的意思:

val list = Seq("a", "b", "c")
m(list: _*)
同样值得注意的是,模式匹配时有一个逆向运算符:

list match {
    case Seq(xs @ _*) => xs.size
    case _            => 0
}

这些是可变长度参数列表(根据规范,如中正确指出的),通常称为“varargs”,是实现此类功能的K&R C库函数的名称

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

Java,它与语法
T有相同的东西。。。arg
,始终以数组[T]的形式传递参数。Scala可以识别Java变量,并可以像Scala一样调用它们

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

public void m(String... args)

String[] list = new String[] { "a", "b", "c" };
m(list)
而在Scala中,您必须使用特殊的语法来明确您的意思:

val list = Seq("a", "b", "c")
m(list: _*)
同样值得注意的是,模式匹配时有一个逆向运算符:

list match {
    case Seq(xs @ _*) => xs.size
    case _            => 0
}

首先,Scala称它们不是“varargs”

与重复形式参数相对应的实际参数被收集到一种特殊的
索引eq
,由
WrappedArray
实现:

scala> def mRP1(ints: Int*): Int = { printf("ints=%s%n", ints); ints.length }
mRP1: (ints: Int*)Int

scala> mRP1(1, 4, 9)
ints=WrappedArray(1, 4, 9)
res0: Int = 3

请注意,因为它们是由一个
IndexedSeq
实现的,所以它们具有固定时间的索引访问。

首先,Scala不调用它们“varargs”

与重复形式参数相对应的实际参数被收集到一种特殊的
索引eq
,由
WrappedArray
实现:

scala> def mRP1(ints: Int*): Int = { printf("ints=%s%n", ints); ints.length }
mRP1: (ints: Int*)Int

scala> mRP1(1, 4, 9)
ints=WrappedArray(1, 4, 9)
res0: Int = 3


请注意,因为它们是由一个
IndexedSeq
实现的,所以它们具有固定时间的索引访问。

这当然是一个相关的问题,但如果一开始不知道此功能的名称,就找不到。@Daniel:这就是问题所在。om nom将问题改为varargs,我正在搜索参数列表。:)这当然是一个相关的问题,但如果一开始不知道该功能的名称,就找不到它。@Daniel:这就是问题所在。om nom将问题改为varargs,我正在搜索参数列表。:)谢谢,我不知道Java也有它们,也不知道它从C开始就存在了/在将Seq传递给函数的scala示例中,
m(list:*)
起作用,但
m(list:Int*)
不起作用。下划线在这里是什么意思?@PlastyGrove它不是真正的下划线,它是
.*
,尽管在这里可以接受空格。这是一种特殊的语法,用于传递列表,就像它是多个参数,而不是其他功能的组合。丹尼尔-谢谢,这很有意义!谢谢,我不知道Java也有它们,也不知道它从C开始就存在了/在将Seq传递给函数的scala示例中,
m(list:*)
起作用,但
m(list:Int*)
不起作用。下划线在这里是什么意思?@PlastyGrove它不是真正的下划线,它是
.*
,尽管在这里可以接受空格。这是一种特殊的语法,用于传递列表,就像它是多个参数,而不是其他功能的组合。丹尼尔-谢谢,这很有意义!非常感谢你的链接!我一直在搜索,不知道该怎么称呼它。我无耻地窃取了你在我自己的答案中输入的所有额外信息。:-)实际上,@om nom nom提供了Scala(第1版)在线编程副本的链接。您在这里没有显示,但实际上有趣的是
mRP1(列表(1,2,3):*)
,即
ints=List(1,2,3)
。所以我们知道,当我们使用
.*
表示法时,Scala编译器没有装箱
Seq
。此外,您声称我们有恒定时间索引访问保证的说法似乎不成立。(
List
有O(n)个索引访问时间。)确实如此。我想这是一种“优化”,直接使用类型兼容的参数源,而不是复制到
WrappedArray
。更有趣(可能令人担忧)的是,同样的优化也适用于以这种方式传递的可变序列参数!非常感谢你的链接!我一直在搜索,不知道该怎么称呼它。我无耻地窃取了你在我自己的答案中输入的所有额外信息。:-)实际上,@om-nom-nom提供了Scala(第1版)在线编程副本的链接