捕获varargs参数的类型

时间:2010-05-05 06:06:20

标签: scala

我想定义一个接受varargs的方法,这样即使在null的情况下,我也可以得到它所调用的类型。

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

3 个答案:

答案 0 :(得分:6)

如果您使用Any作为参数类型,则无法静态确定参数的类型。您必须使用instanceof或模式匹配:

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

不幸的是,这无法处理空值。

如果你想要静态类型,你将不得不使用重载:

def foo[A](arg1: A)
def foo[A, B](arg1: A, arg2: B)
def foo[A, B, C](arg1: A, arg2: B, arg3: C)
...

答案 1 :(得分:4)

就原始问题而言,我很确定这是不可能的。

如果不确切知道你想要实现什么(即,为什么它必须是任意类型的可变长度列表),很难提供替代方案。但是,当我读到可能是您的选项的问题时,我想到了两件事:Default argument values结合命名参数(需要Scala 2.8+)和HList数据类型(不太可能)。

答案 2 :(得分:3)

因为您使用Any作为类型,所以无法获取参数的类型。类型Any没有getClass方法(它甚至根本不是引用类)。有关详细信息,请参阅http://www.scala-lang.org/node/128

您可以尝试的是:

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)

输出:

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