Od samego początku w Kotlin wprowadzono zakresy (Range) w celu uproszczenia operacji na sekwencyjnych zbiorach wartości — jest to dziedziczone z języków o zwięzłej składni do pracy z liczbami (np. Python). Dodatkowo, mechanizm Range został rozszerzony do Progression, pozwalając na określenie kroku iteracji i wspierając różne typy liczb, znaków.
Iteracja po liczbach całkowitych, literach, punktach czasowych itp. często wymaga specjalnej składni i solidnego wsparcia w standardowej bibliotece, w przeciwnym razie kod staje się nieporęczny, nieczytelny i podatny na błędy przy granicach.
W Kotlin istnieją standardowe typy IntRange, CharRange i LongRange, a także Progression do iteracji krokowej. Ponadto można zdefiniować zakresy dla dowolnych porównywalnych typów.
// Prosty zakres for (i in 1..5) print(i) // 12345 // Zakres z krokiem for (i in 1..10 step 2) print(i) // 13579 // Zakres odwrócony for (i in 5 downTo 1) print(i) // 54321 // Własny zakres (np. dla Version) data class Version(val major: Int, val minor: Int): Comparable<Version> { override fun compareTo(other: Version): Int = compareValuesBy(this, other, Version::major, Version::minor) } operator fun ClosedRange<Version>.iterator(): Iterator<Version> = object : Iterator<Version> { var current = start override fun hasNext() = current <= endInclusive override fun next() = current.also { current = Version(current.major, current.minor + 1) } } val v1 = Version(1, 0) val v2 = Version(1, 3) for (v in v1..v2) println(v)
Kluczowe cechy:
.., downTo, until, stepCzym różni się wyrażenie 1..5 od 1 until 5?
1..5 obejmuje oba końce zakresu: 1,2,3,4,5. 1 until 5 nie obejmuje ostatniego elementu: 1,2,3,4.
Czy można zdefiniować zakres z krokiem mniejszym od zera przy użyciu step?
Nie. Dla malejących zakresów użyj konstrukcji downTo, a następnie step: 5 downTo 1 step 2 (otrzymasz 5,3,1).
Czy można używać zakresów z typami, które nie implementują Comparable?
Nie. Aby utworzyć zakres, typ musi wspierać porównanie. W przeciwnym razie kompilator nie pozwoli na definicję.
W kodzie zamiast 1 until n+1 użyto 1..n. Otrzymujemy dodatkowy element, pętla wykracza poza dopuszczalny zakres.
Plusy:
Minusy:
Użyto for (i in 0 until n) do indeksowania tablicy o długości n, zakres dokładnie pokrywa się z dozwolonymi wartościami indeksów.
Plusy:
Minusy: