2013-08-20 63 views
6

我写它接受一个可变参数的参数类,并指定其默认设置,以便用户可以经常实例化它没有指定一个参数:为什么不能指定Scala可变参数的默认值?

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*) { } 

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

回答

5

思考了一下关于这个,我觉得这只是在不增加太多的复杂的问题,假设你有

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

现在,呼叫方使用这样的:f(a)

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

+0

为什么'def foo(result:Int = 0,xs:String *)= ???'是不可接受的呢?编译器将foo(0,“不可能编译”)识别为合法的构造是完全可行的。 –

+0

@ om-nom-nom,不知道我跟着你。我正在回答为什么我们不想支持'def foo(result:Int = 0,xs:String * = Seq(“some”,“default”))= ???'。 – huynhjl

+0

是的,但编译器在我的情况下放置了相同的限制(至少给我们相同的编译错误),所以我猜可能有其他原因统一这两种情况 –

3

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

+2

但是你至少可以做'值:Int * =(Array(42):Int *)' – Jatin

5

从斯卡拉规范(第4.6.2节)

不允许脱科幻NE在参数 部分中的任何缺省参数与重复参数

也许一个解决方法将帮助?

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

它并不能解释它为什么如此,只是假设这种拒绝。 –

2

另一个解决办法是使SEQ明确:

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

是的,这是我结束的解决方法。 – trustin

2

一个默认值可变参数只是没有意义的,因为你不能找出很多争论应如何通过。这不是scala的限制,这是一个合乎逻辑的限制。