将Scala varargs转换为Java Object ... varargs

Gal*_*eño 13 scala scala-2.8

我有一个Java类,它记录的东西有这样的方法:

void info(Object message, Object... params);
Run Code Online (Sandbox Code Playgroud)

在Scala中,我创建了一个围绕这样调用的包装器,如下所示:

def info(msg: => String, params: Any*) {
  log.info(msg, params);
}
Run Code Online (Sandbox Code Playgroud)

我打电话的时候:

val host = "127.0.0.1"
val port = "1234"
info("Start on {0}:{1}", host, port)
Run Code Online (Sandbox Code Playgroud)

我明白了:

"Started on WrappedArray(127.0.0.1, 1234):{1}"
Run Code Online (Sandbox Code Playgroud)

现在,有没有人现在如何将params转换为可以正确使用的Object []?

我试着这样做:

def info(msg: => String, params: Any*)
  log.info(msg, params.toList.toArray);
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用:

"Started on [Ljava.lang.Object;@14a18d:{1}"
Run Code Online (Sandbox Code Playgroud)

你做的时候会发生类似的事情:

params.asInstanceOf[WrappedArray[Object]].array
Run Code Online (Sandbox Code Playgroud)

Gal*_*eño 20

找到答案:

log.info(msg,  params.map(_.asInstanceOf[AnyRef]) : _*)
Run Code Online (Sandbox Code Playgroud)

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

结果:

"Started on 127.0.0.1:1234"
Run Code Online (Sandbox Code Playgroud)

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


oxb*_*kes 12

@Galder - 有一种更简单的方法可以避免繁琐的asInstanceOf[Object]通话:

def info(msg: => String, params: Any*) =  log.info( msg.format(params : _*) );
Run Code Online (Sandbox Code Playgroud)

在scala 2.7中,format(args : Any*)函数隐式包含在内RichString(并且有一个次优实现是反射条件,没有任何理由我可以看到)而在2.8中,该方法包含在via中StringLike并通过直接调用实现String.format(String, Object ...)

我知道Java不包含这种方法的原因是它暗示 "每个String都是一个格式字符串",但实际情况并非如此.幸运的是,我愿意放弃scala提供的更有用的类的逻辑正确性!