tags:

views:

104

answers:

3

Hi,

I'd like to define a method accepting varargs, so that I get the types with which it was called even in the case of nulls.

def foo(args: Any*) = ....

val s: String = null

foo(1, s) // i'd like to be able to tell in foo that args(0) is Int, args(1) is String
+5  A: 

If you're using Any as parameter type you will not be able to determine the type of the arguments statically. You will have to use instanceof or pattern matching:

def foo(args: Any*) = for (a <- args) a match {
  case i: Int =>
  case s: String =>
  case _ =>
}

Unfortuntely, this is not able to handle null values.

If you want static types you will have to use overloading:

def foo[A](arg1: A)
def foo[A, B](arg1: A, arg2: B)
def foo[A, B, C](arg1: A, arg2: B, arg3: C)
...
Michel Krämer
Or use a language that support typed 'varargs' like TypedScheme :)
leppie
+2  A: 

Because you are using Any as type you cannot get the type of the arguments. Type Any doesn't have the getClass method (it even isn't a reference class at all). See http://www.scala-lang.org/node/128 for more information.

What you can try is this:

def foo(args: Any*) = args.map { arg => {
  arg match {
    case reference:AnyRef => reference.getClass.toString
    case null => "null"
}}}

val s: String = null

val result = foo("a", 1, 'c', 3.14, s, new Object, List(1), null)

result.foreach(println)

This outputs:

class java.lang.String
class java.lang.Integer
class java.lang.Character
class java.lang.Double
null
class java.lang.Object
class scala.collection.immutable.$colon$colon
null
michael.kebe
+3  A: 

In terms of the original question, I'm pretty sure it's not possible.

Without knowing exactly what you're trying to achieve (ie, why it must be a variable-length list of arbitrary types), it is difficult to offer an alternative. However, there are two things that came to my mind when I read the question that may be an option for you: Default argument values in combination with named arguments (requires Scala 2.8+), and the HList data type (less likely).

Kristian Domagala