2010-05-05 51 views
3

我想定義一個接受可變參數的方法,這樣即使在空值的情況下也可以獲得它所調用的類型。可變參數的捕獲類型參數

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 
+0

關聯:http://stackoverflow.com/questions/2593510/emulating-variadic-templates-in-scala – 2010-05-18 07:27:06

回答

4

在原來的問題而言,我敢肯定這是不可能的。

不知道你想要達到什麼目的(即爲什麼它必須是任意類型的變長列表),很難提供替代方案。但是,當我讀到可能是您的選項的問題時,出現了兩件事:Default argument values與命名參數(需要Scala 2.8+)以及HList數據類型(較少可能)的組合。

6

如果您使用Any作爲參數類型,你將不能夠靜態確定的參數的類型。你將不得不使用instanceof或模式匹配:

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

Unfortuntely,這是不能夠處理空值。

如果你想靜態類型,你將不得不使用重載:由於您使用Any類型你不能得到的參數的類型

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

或者使用支持typed'varargs'的語言,如TypedScheme :) – leppie 2010-05-05 06:41:27

3

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