问题
I have a Java class that logs stuff which has a method like this:
void info(Object message, Object... params);
In Scala, I've created a wrapper around such call that looks like this:
def info(msg: => String, params: Any*) {
log.info(msg, params);
}
When I call:
val host = "127.0.0.1"
val port = "1234"
info("Start on {0}:{1}", host, port)
I get:
"Started on WrappedArray(127.0.0.1, 1234):{1}"
Now, does anyone now how to convert params into an Object[] that can be consumed properly?
I tried to do:
def info(msg: => String, params: Any*)
log.info(msg, params.toList.toArray);
}
But that doesn't work:
"Started on [Ljava.lang.Object;@14a18d:{1}"
Similar thing happens when you do:
params.asInstanceOf[WrappedArray[Object]].array
回答1:
Found the answer:
log.info(msg, params.map(_.asInstanceOf[AnyRef]) : _*)
The following returns a Seq[AnyRef] => params.map(_.asInstanceOf[AnyRef]), and the ': _*' part tells the compiler to pass it as varargs
Result:
"Started on 127.0.0.1:1234"
Besides, this solution deals with both AnyVals and AnyRefs
回答2:
@Galder - there is an easier way which allows you to avoid the cumbersome asInstanceOf[Object]
call:
def info(msg: => String, params: Any*) = log.info( msg.format(params : _*) );
In scala 2.7, the format(args : Any*)
function is implicitly included via RichString
(and has a sub-optimal implementation is terms of reflection for no good reason that I can see) whereas in 2.8 the method is included via StringLike
and is implemented via a direct call to String.format(String, Object ...)
I understand that the reason why Java does not contain such a method is that it has an implication that "every String is a format String", which is not the case. happily, I'm willing to forgo the logical correctness for the more useable class which scala provides!
来源:https://stackoverflow.com/questions/2334200/transforming-scala-varargs-into-java-object-varargs