为什么不能指定Scala varargs参数的默认值?

时间:2013-08-20 07:10:11

标签: scala variadic-functions default-parameters

我编写了一个接受varargs作为参数的类,并指定了它的默认值,以便用户可以经常实例化它而不指定参数:

class MyClass(values: Int* = 42) { }

但是,编译器和REPL给出了以下错误:

<console>:7: error: type mismatch;
 found   : Int(42)
 required: Int*
       class MyClass(values: Int* = 42) { }
                                ^
<console>:7: error: a parameter section with a `*'-parameter is not allowed to have default arguments
       class MyClass(values: Int* = 42) { }

作为一种解决方法,我尝试了以下方法,但它也不起作用:(显然它很模糊。)

class MyClass(value: Int = 42, otherValues: Int*) { }

我想知道为什么不允许使用varargs参数的默认值。这里有什么理由或技术理由? (我的猜测是指定一个空的varargs需要一些特殊的语法或成语,但我不确定这是否足够的原因。)

5 个答案:

答案 0 :(得分:8)

稍微考虑一下这个问题,我认为只是不要增加太多的复杂性,假设你有

def f(a: A, xs: X* = Seq(x0, x1)) = ???

现在调用者使用如下:f(a)

我们如何知道调用者是否打算传递X*的零长度列表,或者想通过不提供X*来触发默认参数?在您的示例中,您假设第二个替代方案是唯一的情况,并且编译器需要提供默认参数值。但是空Seq()已经是调用者提供的完全有效的值。我猜调用者可以写f(a, Seq(): _*),但这很麻烦。

答案 1 :(得分:6)

来自scala规范(第4.6.2节)

  

不允许在参数中定义任何默认参数   带有重复参数的部分

也许解决方法有帮助吗?

class MyClass(values: Int*) {
  def this() = this(5)
}

答案 2 :(得分:3)

Varargs,不仅在Scala中,是对参数列表的抽象,如果我没有弄错,它会被遗忘到Seq,一个参数列表。从中得出,您对values: Int* = 42的期望是什么?然后,当你调用这个方法时,应该如何将参数传递给这个方法?

答案 3 :(得分:2)

另一种解决方法是使Seq明确:

class MyClass(values: Seq[Int] = Seq(42)) { }

答案 4 :(得分:2)

varargs的默认值没有意义,因为你无法弄清楚应该传递多少个参数。这不是scala的限制,这是一个逻辑限制。