Zakresy (Range) i progresje (Progression) to wbudowany mechanizm w Kotlinie do reprezentowania sekwencji wartości z określonym krokiem. Często są stosowane w pętlach, warunkach, iteracji po kolekcjach i walidacji danych. Zakresy pojawiły się jako jeden ze sposobów, aby uczynić składnię Kotlina bardziej zwięzłą i wyrazistą w porównaniu do Javy.
W Javie podobne zadania rozwiązywano za pomocą pętli for i while z indeksami — co jest mówiąc wprost zbyt obszerne i podatne na błędy. W Kotlinie pojawiły się kompaktowe operatory tworzenia zakresów (na przykład, 1..10) oraz metody do określania kroków.
Kotlin zapewnia standardowe zakresy liczbowe (IntRange, LongRange, CharRange, UIntRange, itd.) oraz interfejsy do tworzenia własnych progresji:
Przykład kodu:
for (i in 1..5) print("$i ") // 1 2 3 4 5 for (i in 5 downTo 1 step 2) print("$i ") // 5 3 1 // Sprawdzenie wartości val x = 42 if (x in 1..100) println("W zakresie!")
Można zdefiniować zakres dla swoich typów, implementując operatory rangeTo i Progression:
data class Version(val major: Int, val minor: Int) : Comparable<Version> { override fun compareTo(other: Version) = compareValuesBy(this, other, Version::major, Version::minor) } operator fun Version.rangeTo(other: Version) = VersionRange(this, other) class VersionRange( override val start: Version, override val endInclusive: Version ) : ClosedRange<Version> for (v in Version(1, 0)..Version(1, 2)) println(v)
Kluczowe cechy:
start..end, downTo, step).in, !in).Co właściwie zwraca wyrażenie 1..5?
Tworzy instancję klasy IntRange, implementującą interfejs ClosedRange<Int>. To nie jest kolekcja, lecz obiekt definiujący granice i krok. Lazy-implementacja.
Dlaczego krok (step) w Range zawsze wynosi 1? Jak zmienić krok?
Domyślnie krok w zakresie wynosi 1 (lub -1 przy downTo). Do innego kroku używane są metody step i downTo. Na przykład:
for (i in 2..10 step 2) println(i)
Czy można używać zakresów z typami, które nie implementują Comparable?
Nie, aby zakres użytkownika działał poprawnie, typ musi implementować interfejs Comparable, w przeciwnym razie operator rangeTo będzie niemożliwy.
step.Programista używa pętli for (i in 5..1) bez downTo, oczekując, że będzie "5, 4, 3, 2, 1", a w rezultacie pętla nie wykona się ani razu.
Zalety:
Wady:
Użycie progresji z downTo i step do iteracji po raportach z wymaganym interwałem, co czyni kod kompaktowym i samodokumentującym się.
Zalety:
Wady: