Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a individual arguments AND a Seq to a var-arg function

I know it's possible to pass individual arguments to a vararg function and it's possible to pass a seq using :_* but is it possible to pass both?

for example:

scala> object X { def y(s: String*) = println(s) }
defined module X

scala> X.y("a", "b", "c")
WrappedArray(a, b, c)

scala> X.y(Seq("a", "b", "c"):_*)
List(a, b, c)

scala> X.y("a", Seq("b", "c"):_*)
<console>:9: error: no `: _*' annotation allowed here
(such annotations are only allowed in arguments to *-parameters)
       X.y("a", Seq("b", "c"):_*)
                             ^

Edit: In Scala 2.10 (in case that matters)

like image 655
GentlemanHal Avatar asked Mar 19 '13 14:03

GentlemanHal


People also ask

What does _* mean in Scala?

: _* is a special instance of type ascription which tells the compiler to treat a single argument of a sequence type as a variable argument sequence, i.e. varargs.

What is variable length arguments in Java?

Java For Testers A method with variable length arguments(Varargs) in Java can have zero or multiple arguments. Variable length arguments are most useful when the number of arguments to be passed to the method is not known beforehand. They also reduce the code as overloaded methods are not required.


2 Answers

Hacky but this should work well:

X.y(Seq("a") ++ Seq("b", "c"):_*)
like image 60
om-nom-nom Avatar answered Oct 10 '22 10:10

om-nom-nom


If you look around in the Scala standard library you'll find this sort of pattern in places:

def doIt(arg: Thing)
def doIt(arg1: Thing, arg2: Thing, moreArgs: Thing*)

You can see this, e.g., in Set.+(...). It allows you to have any number of arguments without ambiguity in the overloads.

Addendum

Proof of concept:

scala> class DI { def doIt(i: Int) = 1; def doIt(i1: Int, i2: Int, iMore: Int*) = 2 + iMore.length }
defined class DI

scala> val di1 = new DI
di1: DI = DI@16ac0be1

scala> di1.doIt(0)
res1: Int = 1

scala> di1.doIt(1, 2)
res2: Int = 2

scala> di1.doIt(1, 2, 3)
res3: Int = 3

scala> di1.doIt(1, 2, List(3, 4, 5): _*)
res4: Int = 5
like image 32
Randall Schulz Avatar answered Oct 10 '22 11:10

Randall Schulz