web-dev-qa-db-ja.com

Kotlin:可変引数に名前付き引数を使用できますか?

たとえば、複雑な署名と可変引数を持つ関数があるとします。

fun complicated(easy: Boolean = false, hard: Boolean = true, vararg numbers: Int)

次のようにこの関数を呼び出すことができるはずです。

complicated(numbers = 1, 2, 3, 4, 5)

残念ながら、コンパイラはこれを許可していません。

可変引数に名前付き引数を使用することは可能ですか?巧妙な回避策はありますか?

26
Jire

varargの後にオプションの引数を移動することで回避できます:

fun complicated(vararg numbers: Int, easy: Boolean = false, hard: Boolean = true) = {}

次に、次のように呼び出すことができます。

complicated(1, 2, 3, 4, 5)
complicated(1, 2, 3, hard = true)
complicated(1, easy = true)

末尾のオプションのパラメータは常に名前で渡す必要があることに注意してください。これはコンパイルされません:

complicated(1, 2, 3, 4, true, true) // compile error

別のオプションは、明示的な配列パラメーターにvararg砂糖を使用しないことです:

fun complicated(easy: Boolean = false, hard: Boolean = true, numbers: IntArray) = {}

complicated(numbers = intArrayOf(1, 2, 3, 4, 5))
22
Vadzim

名前付き引数をvarargパラメーターに渡すには、 スプレッド演算子 を使用します。

complicated(numbers = *intArrayOf(1, 2, 3, 4, 5))
26

Kotlin Docsは次のことを明確に述べています。

可変数の引数(可変引数)

関数のパラメーター(通常は最後のパラメーター)は、vararg修飾子でマークできます。

_fun <T> asList(vararg ts: T): List<T> {
  val result = ArrayList<T>()
  for (t in ts) // ts is an Array
    result.add(t)
  return result
}
_

可変数の引数を関数に渡すことができます:

_  val list = asList(1, 2, 3)
_

関数内では、vararg型のT-パラメーターはTの配列として表示されます。つまり、上記の例のts変数の型は_Array<out T>_。

varargとしてマークできるパラメーターは1つだけです。 varargパラメーターがリストの最後のパラメーターでない場合、次のパラメーターの値は、名前付き引数構文を使用して渡すことができます。パラメーターに関数型がある場合は、括弧の外側にラムダを渡します。

vararg-関数を呼び出すとき、引数を1つずつ渡すことができます。 asList(1, 2, 3)、または、既に配列があり、その内容を関数に渡したい場合は、spread演算子(配列の前に_*_)を付けます:

_val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
_

From: https://kotlinlang.org/docs/reference/functions.html#variable-number-of-arguments-varargs

再開するには、次のようにスプレッド演算子を使用して作成できます。

_complicated(numbers = *intArrayOf(1, 2, 3, 4, 5))
_

それが役立つことを願っています

7
piotrek1543

Varargパラメーターは、パラメーターのリスト内の任意の場所に指定できます。異なるパラメータのセットでどのように呼び出されるかについては、以下の例を参照してください。ところで、呼び出しは閉じ括弧の後にラムダを提供することもできます。

fun varargs(
  first: Double = 0.0,
  second: String = "2nd",
  vararg varargs: Int,
  third: String = "3rd",
  lambda: ()->Unit = {}
) {
  ...
}

fun main(args: Array<String>) {
  val list = intArrayOf(1, 2, 3)

  varargs(1.0, "...", *list, third="third")
  varargs(1.0, "...", *list)
  varargs(1.0, varargs= *list, third="third")
  varargs(varargs= *list, third="third")
  varargs(varargs= *list, third="third", second="...")
  varargs(varargs= *list, second="...")

  varargs(1.0, "...", 1, 2, 3, third="third")
  varargs(1.0, "...", 1, 2, 3)
  varargs(1.0)

  varargs(1.0, "...", third="third")
  varargs(1.0, third="third")
  varargs(third="third")
}
0
C.A.B.