vararg i zasięg zmiennych
Czasem nie wiemy z góry, ile argumentów trafi do funkcji – z pomocą przychodzi
vararg. Poznasz też zasięg zmiennych (gdzie zmienna jest
widoczna) oraz – krótko – funkcje lokalne, czyli funkcje wewnątrz funkcji.
vararg – zmienna liczba argumentów
Słowo vararg przed parametrem pozwala przekazać funkcji
dowolnie wiele argumentów tego samego typu – zero, jeden, kilka
albo kilkadziesiąt. Wewnątrz funkcji trafiają one do jednej nazwy.
fun suma(vararg liczby: Int): Int { var wynik = 0 for (l in liczby) { wynik += l } return wynik } fun main() { println(suma(1, 2, 3)) // 6 println(suma(10, 20)) // 30 println(suma(5)) // 5 println(suma()) // 0 (zero argumentów też jest OK) }
vararg to zbiór wartości
Wewnątrz funkcji parametr vararg zachowuje się jak zbiór
wartości, po którym można przejść pętlą for. Ma też gotowe
właściwości i metody, np. .size (ile elementów) czy .sum().
fun statystyki(vararg oceny: Int) { println("Liczba ocen: ${oceny.size}") println("Suma: ${oceny.sum()}") println("Najwyższa: ${oceny.max()}") } statystyki(5, 3, 4, 6, 2) // Liczba ocen: 5 // Suma: 20 // Najwyższa: 6
Metody .sum(), .max() czy .average() liczą
wynik bez ręcznej pętli. Więcej takich „skrótów” na zbiorach poznasz w bloku
o kolekcjach – tutaj wykorzystujemy je przy okazji vararg.
vararg z innymi parametrami
Funkcja może mieć też zwykłe parametry obok vararg. Aby uniknąć
niejasności, vararg umieszczamy zwykle na końcu listy.
W jednej funkcji może być tylko jeden parametr vararg.
fun raport(tytul: String, vararg wartosci: Int) { println("== $tytul ==") for (w in wartosci) { println("- $w") } } raport("Wyniki klasy", 5, 3, 4)
Jeśli masz już wartości zebrane w jednym miejscu (np. w tablicy), możesz je „rozsypać”
do vararg operatorem *: suma(*tablica).
Tablice i kolekcje poznasz w osobnym bloku – wtedy ten zapis stanie się w pełni jasny.
Zasięg zmiennych
Zasięg to obszar kodu, w którym zmienna jest widoczna i można jej
używać. Zasada jest prosta: zmienna żyje od miejsca deklaracji do końca
bloku { }, w którym powstała.
fun main() { val x = 10 // widoczne w całym main if (x > 5) { val y = 20 // widoczne TYLKO w tym bloku if println(x + y) // OK – x i y są tu widoczne } // println(y) // BŁĄD! y już nie istnieje poza blokiem if }
Parametry funkcji są widoczne tylko w jej wnętrzu, a zmienna pętli (i
w for) – tylko w tej pętli. Dzięki temu nazwy się nie „mieszają”
między różnymi częściami programu.
Funkcje lokalne (krótko)
Funkcję można zdefiniować wewnątrz innej funkcji. Taka funkcja lokalna jest widoczna tylko w funkcji, która ją otacza, i ma dostęp do jej zmiennych. Przydaje się, gdy jakiś fragment logiki powtarza się tylko w jednym miejscu.
fun przywitajWszystkich(vararg imiona: String) { fun przywitaj(imie: String) { // funkcja lokalna println("Cześć, $imie!") } for (imie in imiona) { przywitaj(imie) // wywołanie funkcji lokalnej } } przywitajWszystkich("Anna", "Krzysztof", "Ola")
Funkcja lokalna „widzi” zmienne funkcji, w której się znajduje. To wygodne, ale stosuj ją z umiarem – jeśli fragment logiki przyda się też gdzie indziej, lepiej zrobić z niego zwykłą funkcję na zewnątrz.
Częste błędy
❌ Błąd 1: użycie zmiennej poza jej zasięgiem
❌ Zmienna z if użyta na zewnątrz
if (warunek) {
val wynik = 42
}
println(wynik)
// Błąd! wynik istnieje
// tylko w bloku if
✅ Zadeklaruj w szerszym zasięgu
val wynik = if (warunek) 42 else 0 println(wynik) // wynik widoczny dalej
❌ Błąd 2: traktowanie vararg jak jednej liczby
❌ Działanie wprost na vararg
fun suma(vararg liczby: Int): Int {
return liczby + 1
// Błąd! liczby to zbiór,
// nie pojedyncza liczba
✅ Przejdź po elementach
fun suma(vararg liczby: Int): Int {
var w = 0
for (l in liczby) w += l
return w
}
❌ Błąd 3: dwa parametry vararg
❌ Więcej niż jeden vararg
fun f(vararg a: Int,
vararg b: Int) {}
// Błąd! tylko jeden vararg
// na funkcję
✅ Jeden vararg, na końcu
fun f(etykieta: String,
vararg a: Int) {}
❌ Błąd 4: wywołanie funkcji lokalnej z zewnątrz
❌ Lokalna niewidoczna na zewnątrz
fun zewnetrzna() {
fun lokalna() { }
}
lokalna()
// Błąd! lokalna istnieje
// tylko w zewnetrzna()
✅ Wyciągnij ją na zewnątrz
fun lokalna() { }
fun zewnetrzna() {
lokalna()
}
lokalna()
Podsumowanie
varargpozwala przekazać dowolnie wiele argumentów tego samego typu (także zero).- Wewnątrz funkcji
varargto zbiór wartości – działa zfor, ma.size,.sum()itd. varargumieszczamy zwykle na końcu; może być tylko jeden na funkcję.- Zasięg: zmienna żyje od deklaracji do końca bloku
{ }, w którym powstała. - Parametry i zmienne pętli też mają swój zasięg – nie wychodzą poza swoje miejsce.
- Funkcja lokalna to funkcja wewnątrz funkcji – widoczna tylko w niej i mająca dostęp do jej zmiennych.
Zadania do wykonania
Zadania wykonaj w Kotlin Playground (play.kotlinlang.org).
Napisz funkcję suma(vararg liczby: Int): Int sumującą wszystkie
przekazane liczby. Wywołaj ją z dwiema, czterema i zerem argumentów.
Napisz funkcję statystyki(vararg oceny: Int), która wypisuje liczbę
ocen, ich sumę i średnią. Skorzystaj z .size i .sum().
Napisz fragment kodu, w którym zadeklarujesz zmienną wewnątrz bloku if
i spróbujesz użyć jej poniżej. Zaobserwuj błąd, a następnie popraw kod tak, by
zmienna była widoczna w potrzebnym miejscu.
Napisz funkcję raportSprzedazy(sprzedawca: String, vararg kwoty: Int),
która wypisuje nagłówek z nazwiskiem sprzedawcy, a potem każdą kwotę. Wewnątrz użyj
funkcji lokalnej formatującej pojedynczą kwotę (np. dodającej
„ zł”). Wywołaj funkcję dla kilku kwot.