14

我有一个记录东西的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}"

现在,有人现在如何将参数转换为可以正确使用的 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
4

2 回答 2

22

找到了答案:

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

以下返回一个 Seq[AnyRef] => params.map(_.asInstanceOf[AnyRef]),':_*' 部分告诉编译器将其作为可变参数传递

结果:

"Started on 127.0.0.1:1234"

此外,此解决方案同时处理 AnyVals 和 AnyRefs

于 2010-02-25T13:44:59.720 回答
14

@Galder - 有一种更简单的方法可以让您避免繁琐的asInstanceOf[Object]调用:

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

在 scala 2.7 中,该format(args : Any*)函数是通过隐式包含RichString的(并且有一个次优的实现是反射术语,我看不到没有充分的理由),而在 2.8 中,该方法是通过包含StringLike并通过直接调用来实现的String.format(String, Object ...)

我理解Java之所以不包含这样的方法,是因为它暗示了“每个字符串都是一个格式字符串”,事实并非如此。高兴的是,我愿意放弃 scala 提供的更有用的类的逻辑正确性!

于 2010-02-25T14:58:56.717 回答