--- title: Циклы и диапазоны description: for-in, диапазоны и прогрессии, while, метки и отсутствие классического for tags: - kotlin - syntax --- В Kotlin один цикл обхода - `for (x in source)`. Классического `for (int i = 0; i < n; i++)` нет: его роль выполняют диапазоны. ## Диапазоны ```kotlin for (i in 1..5) print(i) // 12345 — включая 5 for (i in 1..<5) print(i) // 1234 — исключая 5 for (i in 5 downTo 1) print(i) // 54321 for (i in 1..10 step 3) print(i) // 1 4 7 10 for (c in 'a'..'e') print(c) // abcde ``` | Конструкция | Смысл | |---|---| | `a..b` | от `a` до `b` включительно | | `a.. println("итерация $i") } // индекс доступен, с нуля ``` Это не оператор, а [inline-функция](../../Функциональный%20Kotlin/Inline-функции.md) стандартной библиотеки. > [!info] Отличия от Java > | Java | Kotlin | > |---|---| > | `for (int i=0; i | `for (T x : collection)` | `for (x in collection)` | > | `label: for (...)` | `outer@ for (...)` | > | `break label;` | `break@outer` | > | три части в заголовке `for` | только `in` | > | нет диапазонов | `1..10`, `step`, `downTo` | > > Что потеряли: заголовок `for` с несколькими переменными и произвольным условием. Если нужна такая логика - пишется `while`. > > Сравнить: [Циклы в Java](../../../Программирование%20на%20Java/Синтаксис%20и%20типы/Базовый%20синтаксис/Циклы.md) > [!warning] Подводные камни > **`1..5` включает 5.** Самая частая ошибка при переходе с Java: индексы массива - это `0.. ```kotlin > val list = listOf("a", "b", "c") > // for (i in 0..list.size) println(list[i]) // IndexOutOfBounds на i=3 > for (i in 0.. for (i in list.indices) println(list[i]) // ещё лучше > ``` > > **`downTo` со `step` требует положительного шага:** > ```kotlin > for (i in 5 downTo 1 step 2) print(i) // 531 > // for (i in 5 downTo 1 step -2) // IllegalArgumentException в рантайме > ``` > > **Пустой диапазон не ошибка, просто ноль итераций:** > ```kotlin > for (i in 5..1) print(i) // ничего не напечатает > ``` > Молчаливый баг, если границы перепутаны. `(5..1).isEmpty()` - `true`. > > **Коллекцию нельзя изменять во время обхода:** > ```kotlin > val list = mutableListOf(1, 2, 3) > // for (x in list) if (x == 2) list.remove(x) // ConcurrentModificationException > list.removeAll { it == 2 } // правильный способ > ``` > > **Диапазон `Long` и `Char` есть, а `Double` - нет.** `1.0..2.0` создаст `ClosedFloatingPointRange`: проверять `in` можно, но обойти циклом - нельзя (нет `iterator()`). Дополнительно: [Операции над коллекциями](../../Коллекции/Операции.md) Далее: [Строковые шаблоны и вывод](Строковые%20шаблоны%20и%20вывод.md)