vararg în Kotlin

Funcții și lambda Kotlin 1.0

vararg permite unei funcții să primească oricâte argumente de același tip, văzute în corp ca un tablou.

Sintaxă
fun nume(vararg valori: Tip) { ... }   // valori are tipul Array<out Tip>

nume(1, 2, 3)
nume(*tablou)                           // operatorul spread

Ce face vararg

Un parametru marcat vararg acceptă zero, unul sau mai multe argumente: medie(9, 10, 7). În corpul funcției el este un tablou: Array<out T>, sau un tablou de primitive (IntArray pentru vararg x: Int). Așa sunt scrise listOf, setOf, maxOf sau println din Java.

Dacă ai deja un tablou, îl dai cu operatorul spread *: medie(*note). Poți amesteca: medie(5, *note, 10). O listă se transformă întâi în tablou cu toIntArray() sau toTypedArray().

O funcție poate avea un singur parametru vararg. Dacă nu este ultimul, parametrii de după el se dau cu nume.

Exemple

Exemplul 1: Funcție cu oricâte argumente

note este un IntArray. Apelul fără argumente dă un tablou gol.

fun medie(vararg note: Int): Double {
    if (note.isEmpty()) return 0.0
    return note.sum().toDouble() / note.size
}

fun main() {
    println(medie(10, 9, 8))
    println(medie(7))
    println(medie())
    println(medie(5, 6, 7, 8, 9, 10))
}

Rezultat

9.0
7.0
0.0
7.5

Exemplul 2: Operatorul spread *

*semestrul1 desface tabloul în argumente separate. Lista se transformă cu toIntArray().

fun total(vararg sume: Int) = sume.sum()

fun main() {
    val semestrul1 = intArrayOf(120, 80, 45)
    val semestrul2 = listOf(60, 30)
    println(total(*semestrul1))
    println(total(*semestrul1, 100))
    println(total(*semestrul1, *semestrul2.toIntArray()))
}

Rezultat

245
345
335

Exemplul 3: vararg urmat de un parametru cu nume

separator vine după vararg, deci se dă cu nume. T generic face funcția utilă pentru orice tip.

fun <T> listeaza(titlu: String, vararg elemente: T, separator: String = ", "): String =
    "$titlu: ${elemente.joinToString(separator)}"

fun main() {
    println(listeaza("Orașe", "Iași", "Cluj", "Timișoara"))
    println(listeaza("Note", 10, 9, 7, separator = " | "))
    println(listeaza<String>("Gol"))
}

Rezultat

Orașe: Iași, Cluj, Timișoara
Note: 10 | 9 | 7
Gol:

Greșeli frecvente

  • Trimiterea unui tablou fără *: total(semestrul1) dă eroare de tip (se așteaptă Int, s-a primit IntArray).
  • Trimiterea unei liste cu spread: *lista nu merge direct, transformă întâi lista în tablou (*lista.toTypedArray()).
  • Două parametri vararg în aceeași funcție: nu este permis.

Comenzi înrudite

  • fun: fun declară o funcție: un bloc de cod cu nume, care primește parametri și poate returna un rezultat.
  • arrayOf: Creează un tablou (Array) cu dimensiune fixă din elementele date; intArrayOf creează un tablou de Int primitive.
  • listOf: Creează o listă din elementele date: listOf pentru citire, mutableListOf și arrayListOf pentru o listă pe care o modifici.
  • Generics (<T>) și where: Generics permit clase și funcții care lucrează cu orice tip (T), verificat la compilare; where adaugă mai multe restricții pe T.