web-dev-qa-db-fra.com

Kotlin: Pouvez-vous utiliser des arguments nommés pour varargs?

Par exemple, vous pourriez avoir une fonction avec une signature compliquée et des variables différentes:

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

Il serait logique que vous puissiez appeler cette fonction comme suit:

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

Malheureusement, le compilateur ne le permet pas.

Est-il possible d'utiliser des arguments nommés pour varargs? Existe-t-il des solutions intelligentes?

24
Jire

On peut contourner ce problème en déplaçant des arguments optionnels après la vararg:

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

Ensuite, il peut s'appeler comme ceci:

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

Notez que les derniers paramètres optionnels doivent toujours être passés avec le nom ..__ Ceci ne compilera pas:

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

Une autre option est d’épargner le sucre vararg pour le paramètre de tableau explicite:

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

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

Pour passer un argument nommé à un paramètre vararg, utilisez l'opérateur spread :

complicated(numbers = *intArrayOf(1, 2, 3, 4, 5))
21
Alexander Udalov

Kotlin Docs dit clairement que:

Nombre variable d'arguments (Varargs)

Un paramètre d'une fonction (normalement la dernière) peut être marqué avec vararg modificateur:

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
}

permettant à un nombre variable d'arguments d'être passés à la fonction:

  val list = asList(1, 2, 3)

Dans une fonction, un paramètre vararg- de type T est visible en tant que tableau de T, c’est-à-dire que la variable ts dans l’exemple ci-dessus a le type Array<out T>.

Un seul paramètre peut être marqué en tant que vararg. Si un paramètre vararg n'est pas le dernier de la liste, valeurs pour les paramètres suivants peut être passé en utilisant la syntaxe de l'argument nommé, ou, si le paramètre a un type de fonction, en passant un lambda en dehors des parenthèses.

Lorsque nous appelons une fonction vararg-, nous pouvons passer les arguments un par un, par exemple. asList(1, 2, 3), ou, si nous avons déjà un tableau et voulons le faire transmettez son contenu à la fonction, nous utilisons l'opérateur spread (préfixez le tableau avec *):

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

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

Pour résumer, vous pouvez le faire en utilisant l'opérateur spread afin qu'il ressemble à ceci:

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

J'espère que ça va aider

6
piotrek1543

Le paramètre vararg peut figurer n'importe où dans la liste de paramètres. Voir l'exemple ci-dessous pour savoir comment il peut être appelé avec différents jeux de paramètres. BTW tout appel peut également fournir lambda après parenthèses fermées.

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.