2010-02-25 94 views
12

我有記錄的東西其中有這樣的方法的Java類:轉化Scala的可變參數爲Java對象...可變參數

void info(Object message, Object... params); 

在Scala中,我創建了身邊有這樣的呼叫,看起來像一個包裝這樣的:

def info(msg: => String, params: Any*) { 
    log.info(msg, params); 
} 

當我打電話:

val host = "127.0.0.1" 
val port = "1234" 
info("Start on {0}:{1}", host, port) 

我得到:

"Started on WrappedArray(127.0.0.1, 1234):{1}" 

現在,有沒有人現在如何將PARAMS轉換成可以正確使用的Object []?

我試圖做的:

def info(msg: => String, params: Any*) 
    log.info(msg, params.toList.toArray); 
} 

但是,這並不工作:

"Started on [Ljava.lang.Object;@14a18d:{1}" 

類似的事情發生在你:

params.asInstanceOf[WrappedArray[Object]].array 

回答

19

找到了答案:

log.info(msg, params.map(_.asInstanceOf[AnyRef]) : _*) 

下面返回一個序號[AnyRef] => params.map(_ asInstanceOf [AnyRef]),而 ':_ *' 部分告訴編譯器將其作爲可變參數

結果:

"Started on 127.0.0.1:1234" 

此外,既AnyVals和AnyRefs

+0

我可以問你'info(「開始於{0}:{1}」,主機,端口)'是怎麼變成「127.0.0.1:1234開始的」?它是你的標準RichString的代碼嗎? – Andrey 2010-02-25 22:58:00

+0

這通過提供給我的一些Java代碼進行轉換。該格式的方法在http://anonsvn.jboss.org/repos/infinispan/trunk/core/src/main/java/org/infinispan/util/Util.java中稱爲formatString – 2010-03-03 14:56:20

+0

感謝您的解決方案。你爲什麼不把它標記爲答案? – 2011-10-10 05:38:58

12

@Galder這個解決方案的交易 - 有一個更簡單的方法,讓您避免繁瑣的asInstanceOf[Object]電話:

def info(msg: => String, params: Any*) = log.info(msg.format(params : _*)); 

在階2.7時,format(args : Any*)函數被隱含經由RichString包括(並且具有次優的實施,是沒有充分的理由,我可以看到反射計)經由StringLike被包括在方法,而在2.8和經由被實現直接調用String.format(String, Object ...)

我明白爲什麼Java不包含這種方法的原因是,它有一個蘊含「每個字符串是一個格式字符串」,這是不是這樣的。高興地說,我願意放棄scala提供的更有用的類的邏輯正確性!

+0

這將創建一個日誌字符串在任何情況下熱切,對吧? – 2010-02-25 18:41:44

+0

這不會編譯,它會與存在的其他版本的log.info混淆。它無法區分: void info(Object message);和 void info(Object message,Object ... params); – 2010-03-03 14:50:57

+0

這對我來說是新聞 - 它直接從我的生產代碼中解脫出來! – 2010-03-03 15:25:59