我编写了一个接受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需要一些特殊的语法或成语,但我不确定这是否足够的原因。)
答案 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的限制,这是一个逻辑限制。