Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I forward repeated arguments in Scala?

Tags:

scala

In Scala (2.7), if I have this function:

def foo(args: Array[String]) =
  for (arg <- args) println(arg)

If I now try to define the following:

def bar(args: String*) = foo(args)

then the compiler complains:

<console>:5: error: type mismatch;
 found   : String*
 required: Array[String]
       def bar(args: String*) = foo(args)
                                ^

I don't understand this error, since the Programming Scala book states that the type of args inside function bar is actually Array[String]. How am I supposed to write such a wrapper function with repeated arguments?

like image 660
lindelof Avatar asked Jul 13 '10 20:07

lindelof


People also ask

What is Vararg Scala?

Scala varargs In Scala, the last argument of the method can be of variable argument i.e. it can be repeated the multiple numbers of times in the parameter list of the method. In this function, the programmer can pass multiple arguments. The varargs are stored as an array of the same data type i.e. array [data_type].

What does asterisk mean in Scala?

That's what the : _* notation is for: it tells the Scala compiler "treat this as a sequence of parameters for varargs".


1 Answers

scala> def foo(args: Array[String]) = for(arg <- args) println(arg)
foo: (args: Array[String])Unit

scala> def bar(args: String*) = foo(args.toArray)
bar: (args: String*)Unit

scala> bar("hello", "world")
hello
world

You need to perform above conversion because varargs in Scala are implemented as Seq, not Array.


Here is how varargs are usually forwarded in Scala:

scala> def fooV(args: String*) = args foreach println
fooV: (args: String*)Unit

scala> def fooS(args: Seq[String]) = fooV(args: _*)
fooS: (args: Seq[String])Unit

scala> def bar(args: String*) = fooV(args: _*)
bar: (args: String*)Unit

scala> def barS(args: Seq[String]) = args foreach println
barS: (args: Seq[String])Unit

scala> def barV(args: String*) = barS(args)
barV: (args: String*)Unit

scala> def barV(args: String*) = barS(args.toSeq)
barV: (args: String*)Unit
like image 68
missingfaktor Avatar answered Nov 15 '22 12:11

missingfaktor