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 n开发者_Go百科ulls.
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
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)
...
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).
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
精彩评论