Javaのメソッドで可変長引数を扱う場合は、 <型>... 仮引数名
という記述で引数の部分を記述します。
例えば、与えられた可変長の文字列群をList化して出力するメソッドなら以下の様になります。
import java.util.Arrays; void convToListAndPrint(String... values) { System.out.println((Arrays.asList(values))); }
呼び出し側のコードは以下の様になります
convToListAndPrint("Str1", "Str2", "Str3");
実行結果は以下の通りです
[Str1, Str2, Str3]
可変長引数で渡されたパラメータは 配列 として扱われています。
以下の様に可変長引数部分に 配列を渡してメソッドを呼び出すことも可能です
convToListAndPrint(new String[] {"Str1", "Str2", "Str3"}); // -> [Str1, Str2, Str3]
Kotlinにおける可変長引数
Kotlinでは可変長引数として取る引数には、vararg
修飾子をつけます。
さきほどJavaのメソッドとして書いた convToListAndPrint をKotlinで書き直すと以下の様になります。
関数のパラメータにvararg
修飾子が付いている部分も当然異なっていますが、
Arrays.asList
に可変長引数として受け取ったパラメータに *
を付与している部分も違います。
fun convToListAndPrint(vararg values: String) { println(Arrays.asList(*values)) }
Kotlinでは、可変長引数をとる関数に 配列を渡す事ができません。可変長引数で受け取った values は、配列として格納されています。
これを、可変長引数を必要とする Arrays.asList
には直接渡せません。
引数の前に*
を置く スプレット演算子 というもので、配列の全要素を展開した状態にします。
これにより受け渡しが可能となっています。
以下の呼び出しは可能ですが、
convToListAndPrint("Str1", "Str2", "Str3")
以下の呼び出しはできません。コンパイルエラーになります
// コンパイルエラー val array: Array<String> = arrayOf("Str1", "Str2", "Str3", "Str4") convToListAndPrint(array)
スプレット演算子を利用した以下の呼び出しなら可能です
val array: Array<String> = arrayOf("Str1", "Str2", "Str3", "Str4") convToListAndPrint(*array)
また、Javaでは可変長引数のパラメータは、一番最後の引数としてしか指定できません。
以下の様なコードはコンパイルエラーになります
import java.time.LocalDate; import java.util.Arrays; // コンパイルエラー(可変長引数の位置が不適切) void convToListAddDateAndPrint(String... values, LocalDate date) { System.out.println(Arrays.asList(values).add(date.toString())); }
ただし、Kotlinではこの縛り無いようで?、以下のようなコードは問題ありません。
import java.time.LocalDate; import java.util.Arrays; fun convToListAddDateAndPrint(vararg values: String, date: LocalDate) { println(Arrays.asList(*values).add(date.toString())) }
呼び出す場合は、以下のように可変長引数以外のパラメータには名前付き引数を利用する必要があるようです。
(この辺りは、私の調べが足りてないだけかも?)
convToListAddDateAndPrint( "Str1", "Str2", "Str3", date = LocalDate.now())
まとめ
KotlinでもJavaと同様に可変長引数を扱える事が分かりました。
ただし、いくつかJavaとは異なる部分があり、意識する必要があります。