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}"

さて、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
4

2 に答える 2

22

答えが見つかりました:

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

以下はSeq[AnyRef]=> params.map(_。asInstanceOf [AnyRef])を返し、':_*'部分はコンパイラにvarargsとして渡すように指示します

結果:

"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 に答える