メモ2ブログ

メモtoウェブログ。旧ブログはこちら。 http://sakebook.blogspot.jp/

Kotlinの可変長引数とフォーマット

Kotlinの可変長引数とフォーマットを利用した置き換えで詰まったのでメモ

可変長引数

メソッドの引数として定義するときは vararg を付けます。

fun someMethod(vararg args: String) {
    args.forEach { 
        println(it)
    }
}

someMethod("one") // ok
someMethod("one, two") // ok
someMethod(arrayOf("one", "two")) // error
someMethod(arrayListOf("one", "two")) // error

フォーマット

文字列内で置き換えできるやつです。

fun greet(name: String): {
    val greetText = "Hello %s."
    println(greetText.format(name))
}

greet("kotlin") // Hello kotlin.

ハマったとこ

可変長引数の展開

次のようなフォーマットに対して

val singleGreet = "Hello %s."

次の2つは結果が異なります。

  • フォーマットに直接指定
singleGreet.format("everyone")
// Hello everyone.
  • フォーマットに関数を経由して指定
fun greet(vararg args: String) {
    singleGreet.format(args)
}
greet("everyone")
// Hello [Ljava.lang.String;@30dae81.

これは、greet関数の引数で可変長引数としているため、formatにはArrayとして利用されるからです。

避けるためには、可変長引数を展開してあげる必要があります。 展開するには、可変長引数の先頭に * を付けます。(spread演算子)

  • 可変長引数を展開
fun greet(vararg args: String) {
    singleGreet.format(*args)
}
greet("everyone")
// Hello everyone.

どちらもコンパイルが通るのでアレですが、空気を読んでほしかった部分はあります。

冒頭で書いた関数も、spread演算子を使えばコンパイルが通ります。

someMethod(*arrayOf("one", "two")) // ok

フォーマットが複数ある場合も展開するときれいに収まります。

val multiGreet = "Hello %1\$s, and %2\$s."
// これでも出来るが `*` を使うほうが変更に強い
fun greetMultiNoSpread(vararg args: String) {
    multiGreet.format(args[0], args[1])
}
greetMultiNoSpread("mother", "father")
// Hello mother, and father.

fun greetMulti(vararg args: String) {
    multiGreet.format(*args)
}
greetMulti("mother", "father")
// Hello mother, and father.

raw stringsでの展開

"3つで囲むやつです。改行などもそのまま出力できます。

フォーマットが複数ある場合は $ を使う必要があるのですが、raw stringsだとバックスラッシュでのエスケープができません。

val rawEscapedMultiGreet = """
    |Hello %1\$s.
    |Hello %2\$s.
""".trimMargin()
// Unresolved reference: s
// コンパイルエラー

次のように書きます。

val rawMultiGreet = """
    |Hello %1${'$'}s.
    |Hello %2${'$'}s.
""".trimMargin()

${}のString Templatesを利用して$に置き換えます。

参考

KotlinでString.formatを使う / Qiita

Variable number of arguments (Varargs) / Kotlin Programming Language

String Templates / Kotlin Programming Language