为什么无法指定Scala varargs参数的默认值?

为什么无法指定Scala varargs参数的默认值?,scala,variadic-functions,default-parameters,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) { }

我编写了一个类,该类接受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) { }

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

varargs,不仅在Scala中,是一个参数列表的抽象,如果我没有错的话,它被分解为
Seq
,一个参数列表。由此得出,您希望从
值:Int*=42
得到什么结果?然后,当您调用此方法时,应如何将参数传递到此方法?

来自scala规范(第4.6.2节)

不允许在参数中定义任何默认参数 具有重复参数的节

也许一个变通办法会有帮助

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

另一个解决方法是使Seq显式:

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

varargs的默认值毫无意义,因为您无法计算应该传递多少个参数。这不是scala的限制,这是一个逻辑限制。

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

def f(a: A, xs: X* = Seq(x0, x1)) = ???
现在调用者这样使用:
f(a)


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

但是您至少可以执行
values:Int*=(数组(42):Int*)
为什么
def foo(结果:Int=0,xs:String*)=???
是不可接受的?编译器完全可以将
foo(0,“不可能编译”)
识别为合法的构造。@om nom nom,我不确定我是否明白你的意思。我在回答为什么我们可能不想支持
def foo(result:Int=0,xs:String*=Seq(“some”,“default”))=???
。是的,但编译器对我的情况施加了非常相同的限制(至少给了我们相同的编译错误),所以我想可能还有其他一些原因将这两种情况统一起来。我没有解释为什么会这样,只是假设这样的否认。
def f(a: A, xs: X* = Seq(x0, x1)) = ???