Why is it impossible to specify the default value of the Scala varargs parameter?

I wrote a class that takes varargs as a parameter and sets it to default so that the user can often create it without specifying a parameter:

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

However, the compiler and REPL give me the following errors:

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

As a workaround, I tried the following, but it didn't work either: (this is very ambiguous).

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

I wonder why it is not allowed to use the default varargs parameter. What is the reason or technical reason? (My assumption is that specifying empty varargs will require some special syntax or idiom, but I'm not sure if this is sufficient reason.)

+6
source share
5 answers

Thinking a little about it, I think it’s just a matter of not too complicated work, suppose you have

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

Now the caller uses the following: f(a) .

How do we know if the caller should pass a null list from X* or would like to call the default arguments without providing X* ? In your example, you assume that the second option is the only case that will ever be, and that the compiler should provide a default argument value. But empty Seq() already a valid value provided by the caller. I think the caller could write f(a, Seq(): _*) , but this is cumbersome.

+6
source

From the scala specification (section 4.6.2)

Cannot define default arguments in a section parameter with a repeating parameter

Perhaps a workaround will help?

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

Varargs, and not just in Scala, is an abstraction over the argument list; if I'm not mistaken, it is desugared in Seq , the argument list. Based on this, what result do you expect from values: Int* = 42 ? And then, when you call this method, how should the arguments be passed to this method?

+3
source

Another solution is to make Seq explicit:

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

The default value for varargs simply does not make sense, since you cannot determine how many arguments should be passed. This is not a scala restriction; it is a logical restriction.

+2
source

Source: https://habr.com/ru/post/952082/


All Articles