6

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

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 参数的默认值。这里的推理或技术原因是什么?(我的猜测是,指定一个空的可变参数需要一些特殊的语法或习惯用法,但我不确定这是否是一个足够的理由。)

4

5 回答 5

8

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

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

现在调用者这样使用:f(a).

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

于 2013-08-20T13:09:26.170 回答
6

来自 scala 规范(第 4.6.2 节)

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

也许解决方法会有所帮助?

class MyClass(values: Int*) {
  def this() = this(5)
}
于 2013-08-20T07:19:27.447 回答
3

不仅在 Scala 中,Varargs 是对参数列表的抽象,如果我没记错的话,它被简化为Seq参数列表。由此得出,您期望得到什么结果values: Int* = 42?然后,当你调用这个方法时,应该如何将参数传递给这个方法?

于 2013-08-20T07:15:06.707 回答
2

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

class MyClass(values: Seq[Int] = Seq(42)) { }
于 2013-08-20T07:20:58.747 回答
2

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

于 2013-08-20T08:24:32.290 回答