Подтвердить что ты не робот

Преобразование Scala varargs в объект Java... varargs

У меня есть класс 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
4b9b3361

Ответ 1

Найден ответ:

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

Возвращает Seq [AnyRef] = > params.map(_. asInstanceOf [AnyRef]), а часть ': _ *' сообщает компилятору передать его как varargs

Результат:

"Started on 127.0.0.1:1234"

Кроме того, это решение касается как AnyVals, так и AnyRefs

Ответ 2

@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 предоставляет!