Desde el principio, Kotlin introdujo rangos (Range) para simplificar las operaciones con conjuntos consecutivos de valores; esto se ha heredado de lenguajes con una sintaxis concisa al trabajar con números (por ejemplo, Python). Además, el mecanismo Range se amplió a Progression, permitiendo especificar el paso de iteración y soportar diferentes tipos de números y caracteres.
Iterar sobre números enteros, letras, puntos en el tiempo, etc. a menudo requiere una sintaxis especial y un soporte confiable en la biblioteca estándar, de lo contrario, el código se vuelve voluminoso, ilegible y propenso a errores de límites.
En Kotlin hay tipos estándar IntRange, CharRange y LongRange, así como Progression para la iteración con pasos. Además, se pueden definir rangos para tipos comparables arbitrarios.
// Rango simple for (i in 1..5) print(i) // 12345 // Rango con paso for (i in 1..10 step 2) print(i) // 13579 // Rango inverso for (i in 5 downTo 1) print(i) // 54321 // Rango personalizado (por ejemplo, para 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)
Características clave:
.., downTo, until, step¿Cuál es la diferencia entre la expresión 1..5 y 1 until 5?
1..5 incluye ambos extremos del rango: 1,2,3,4,5. 1 until 5 no incluye el último elemento: 1,2,3,4.
¿Se puede definir un rango con un paso menor que cero utilizando step?
No. Para rangos decrecientes, utiliza la construcción downTo, luego step: 5 downTo 1 step 2 (obtendrás 5,3,1).
¿Se pueden utilizar rangos con tipos que no implementan Comparable?
No. Para crear un rango, el tipo debe soportar comparación. De lo contrario, el compilador no permitirá la definición.
En el código, en lugar de 1 until n+1, se utilizó 1..n. Obtenemos un elemento adicional, el ciclo excede los límites del rango permitido.
Ventajas:
Desventajas:
Se utiliza for (i in 0 until n) para indexar un arreglo de longitud n, el rango coincide exactamente con los valores válidos de los índices.
Ventajas:
Desventajas: