Scala:为什么一个方法不能有多个可变参数?
Scala: Why can't a method have multiple vararg arguments?
谁能告诉我为什么存在这个限制?它与 JVM 或 Scala 编译器有关吗?
$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def toText(ints: Int*, strings: String*) = ints.mkString("") + strings.mkString("")
<console>:7: error: *-parameter must come last
def toText(ints: Int*, strings: String*) = ints.mkString("") + strings.mkString("")
Scala 基于 Java 虚拟机,它被设置为只接受可变参数作为最后一个参数,每个方法参数集只接受一个。没有解决这个问题,这就是编译器的工作方式。
为了正确看待它,想象一个像这样的方法签名:
someMethod(strings1: String*, strings2: String*)
假设您在调用它时传递了 4 个单独的字符串。编译器不知道哪个 String 对象属于哪个可变参数。
如果您使用多个参数列表(curried 语法),Scala 可以 有多个可变参数:
scala> def toText(ints: Int*)(strings: String*) =
ints.mkString("") + strings.mkString("")
scala> toText(1,2,3)("a", "b")
res0: String = 123ab
更新:单个参数列表中的多个可变参数会产生语法问题 - 编译器如何知道给定参数属于哪个参数(一个参数列表在哪里结束, 和下一个开始,特别是如果它们是兼容的类型?)。
理论上,如果修改语言的语法以便可以区分第一个和第二个参数列表(无需柯里化),那么这在 JVM 级别没有理由不起作用,因为可变参数只是编译反正成一个数组。
但我非常怀疑这是一个足够常见的案例来证明进一步复杂化语言是合理的,尤其是当解决方案已经存在时。
另见 this related Java question and answer。
谁能告诉我为什么存在这个限制?它与 JVM 或 Scala 编译器有关吗?
$ scala
Welcome to Scala version 2.10.4 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def toText(ints: Int*, strings: String*) = ints.mkString("") + strings.mkString("")
<console>:7: error: *-parameter must come last
def toText(ints: Int*, strings: String*) = ints.mkString("") + strings.mkString("")
Scala 基于 Java 虚拟机,它被设置为只接受可变参数作为最后一个参数,每个方法参数集只接受一个。没有解决这个问题,这就是编译器的工作方式。
为了正确看待它,想象一个像这样的方法签名:
someMethod(strings1: String*, strings2: String*)
假设您在调用它时传递了 4 个单独的字符串。编译器不知道哪个 String 对象属于哪个可变参数。
如果您使用多个参数列表(curried 语法),Scala 可以 有多个可变参数:
scala> def toText(ints: Int*)(strings: String*) =
ints.mkString("") + strings.mkString("")
scala> toText(1,2,3)("a", "b")
res0: String = 123ab
更新:单个参数列表中的多个可变参数会产生语法问题 - 编译器如何知道给定参数属于哪个参数(一个参数列表在哪里结束, 和下一个开始,特别是如果它们是兼容的类型?)。
理论上,如果修改语言的语法以便可以区分第一个和第二个参数列表(无需柯里化),那么这在 JVM 级别没有理由不起作用,因为可变参数只是编译反正成一个数组。
但我非常怀疑这是一个足够常见的案例来证明进一步复杂化语言是合理的,尤其是当解决方案已经存在时。
另见 this related Java question and answer。