2010-02-25 97 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