Bereiche (Range) und Progressionen (Progression) sind ein integriertes Mittel in Kotlin zur Darstellung von Wertfolgen mit einem bestimmten Schritt. Sie werden häufig bei der Arbeit mit Schleifen, Bedingungen, der Iteration über Sammlungen und der Validierung von Daten eingesetzt. Range wurde als einer der Wege eingeführt, um die Syntax von Kotlin im Vergleich zu Java kürzer und ausdrucksvoller zu gestalten.
In Java wurden ähnliche Aufgaben über Schleifen wie for und while mit Indizes gelöst – umständlich und fehleranfällig. In Kotlin gibt es kompakte Operatoren zur Erstellung von Bereichen (zum Beispiel, 1..10) und Methoden zur Festlegung von Schritten.
Kotlin bietet Standardzahlenbereiche (IntRange, LongRange, CharRange, UIntRange usw.) und Schnittstellen zur Erstellung eigener Progressionen:
Beispielcode:
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 // Wertprüfung val x = 42 if (x in 1..100) println("Im Bereich!")
Man kann einen Bereich für die eigenen Typen definieren, indem man die Operatoren rangeTo und Progression implementiert:
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)
Schlüsselmerkmale:
start..end, downTo, step).in, !in).Was gibt der Ausdruck 1..5 tatsächlich zurück?
Er erstellt eine Instanz der Klasse IntRange, die das Interface ClosedRange<Int> implementiert. Das ist keine Sammlung, sondern ein Objekt, das die Grenzen und den Schritt definiert. Lazy-Implementierung.
Warum beträgt der Schritt (step) bei Range immer 1? Wie kann man den Schritt ändern?
Standardmäßig beträgt der Schritt für den Bereich 1 (oder -1 bei downTo). Für einen anderen Schritt werden die Methoden step und downTo verwendet. Zum Beispiel:
for (i in 2..10 step 2) println(i)
Kann man Bereiche mit Typen verwenden, die nicht Comparable implementieren?
Nein, für die korrekte Funktionsweise eines benutzerdefinierten Bereichs muss der Typ das Interface Comparable implementieren, sonst ist der Operator rangeTo nicht möglich.
step zu ändern.Ein Entwickler verwendet eine Schleife for (i in 5..1) ohne downTo und erwartet, dass sie "5, 4, 3, 2, 1" ausgibt, aber die Schleife wird kein einziges Mal ausgeführt.
Vorteile:
Nachteile:
Einsatz von Progressionen mit downTo und step zur Iteration über Berichte mit dem gewünschten Intervall, wodurch der Code kompakt und selbstdokumentierend wird.
Vorteile:
Nachteile: