2010-02-25 32 views
12

que tienen una clase Java que registra cosas que tiene un método como este:Transformación Scala varargs en Java Object ... varargs

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

En Scala, he creado una envoltura alrededor de dicha llamada que parece esto:

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

Cuando llamo:

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

me sale:

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

Ahora, ¿alguien ahora cómo convertir params en un objeto [] que se puede consumir correctamente?

he tratado de hacer:

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

Pero eso no funciona:

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

Algo similar sucede cuando haces:

params.asInstanceOf[WrappedArray[Object]].array 

Respuesta

19

encontrado la respuesta:

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

Las siguientes declaraciones de una Sec [AnyRef] => params.map (_ asInstanceOf [AnyRef].), Y la: parte '_ *' indica al compilador que pasan como varargs

Resultado:

"Started on 127.0.0.1:1234" 

Además, esta solución se ocupa de ambos AnyVals y AnyRefs

+0

¿Puedo preguntarte cómo 'info ("Start on {0}: {1}", host, port)' se transforma en "Started on 127.0.0.1:1234"? ¿Es su código su estándar RichString? – Andrey

+0

Esto es transformado por algún código Java que se me proporcionó. El método que formatea se llama formatString en http://anonsvn.jboss.org/repos/infinispan/trunk/core/src/main/java/org/infinispan/util/Util.java –

+0

Gracias por la solución. ¿Por qué no lo marcas como una respuesta? –

12

@Galder - hay una manera más fácil que le permite evitar el engorroso asInstanceOf[Object] llamada:

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

en Scala 2.7, la función format(args : Any*) se incluye implícitamente a través de RichString (y tiene una aplicación subóptima es materia de reflexión para ninguna buena razón que puedo ver) mientras que en 2.8 el método se incluye a través StringLike y se implementa a través una llamada directa a String.format(String, Object ...)

entiendo que la razón por la Java no contiene un procedimiento de este tipo es que tiene una implicación que "cada cadena es un formato de cadena", que no es el caso. ¡felizmente, estoy dispuesto a renunciar a la corrección lógica de la clase más útil que ofrece scala!

+0

Esto creará una cadena de registro en cualquier caso con impaciencia, ¿verdad? –

+0

Eso no se compila, se confunde con la otra versión de log.info que existe.No puede diferenciar entre: información de vacío (mensaje de objeto); y información de vacío (mensaje de objeto, Object ... params); –

+0

¡Eso es nuevo para mí, se ha eliminado directamente de mi código de producción! –

Cuestiones relacionadas