Циклы и перебор коллекций
Циклы позволяют повторять действия: пройти по списку задач, просуммировать числа, обработать каждый элемент.
Суть урока: в Swift основной инструмент — for-in. Он напрямую перебирает элементы коллекции, не возясь с индексами, что делает код чище и безопаснее.
Самый частый цикл — for-in. Он берёт каждый элемент коллекции по очереди:
let names = ["Анна", "Борис", "Вера"]
for name in names {
print("Привет, \(name)")
}
for number in 1...5 { // по диапазону
print(number * number)
}Если нужны и индекс, и значение — есть enumerated(). А для перебора с шагом — stride:
for (index, name) in names.enumerated() {
print("\(index): \(name)")
}
for even in stride(from: 0, to: 10, by: 2) {
print(even) // 0, 2, 4, 6, 8
}Словарь перебирается парами ключ-значение:
let scores = ["Анна": 95, "Борис": 88]
for (name, score) in scores {
print("\(name) набрал \(score)")
}Когда число повторов заранее неизвестно, помогает while (проверка до тела) и repeat-while (тело хотя бы раз, потом проверка):
var countdown = 3
while countdown > 0 {
print(countdown)
countdown -= 1
}
print("Старт!")Попробуй сам ▶ — запусти код прямо в браузере (Pyodide). Здесь нет Swift, но логика та же, что под капотом мобильного кода:
# for-in, enumerate и while — всё это есть и в Python, логика та же.
names = ['Анна', 'Борис', 'Вера']
for i, name in enumerate(names): # как .enumerated()
print(i, name)
for even in range(0, 10, 2): # как stride(from:to:by:)
print('чёт', even)
countdown = 3
while countdown > 0:
print(countdown)
countdown -= 1
print('Старт!')Как работает под капотом
За for-in стоит протокол Sequence и его итератор: цикл вызывает next(), пока не получит nil. Это значит, что перебирать можно не только массивы, но и любые типы, которые реализуют этот протокол — диапазоны, строки (по символам), даже собственные структуры. Перебор по элементам, а не по индексам, исключает классическую ошибку «выход за границу» и делает код декларативнее.
Частые ошибки
- Менять коллекцию во время её перебора. Добавление или удаление элементов внутри for-in приводит к непредсказуемому поведению.
- Бесконечный while. Забыли изменить условие — цикл не закончится и приложение зависнет.
- Городить ручные индексы там, где хватит for-in. Это лишний код и риск ошибки.
Best practices
- Предпочитайте for-in циклу по индексам; используйте enumerated(), когда индекс действительно нужен.
- Для досрочного выхода используйте break, для пропуска итерации — continue.
- Если цикл лишь преобразует данные — присмотритесь к map/filter из следующего урока.
Итоги. for-in — главный цикл Swift, он перебирает элементы напрямую и работает с любой последовательностью. while и repeat-while нужны, когда число повторов неизвестно. Скоро вы увидите, что многие циклы элегантнее заменить функциональными методами.
Шире контекста
Понимание протокола Sequence за циклом for-in открывает целый мир. Перебирать можно не только массивы, но и диапазоны, строки посимвольно, ключи и значения словаря, и даже ваши собственные типы, если они умеют выдавать элементы по одному. Это объясняет, почему один и тот же синтаксис цикла работает с таким разным содержимым — за ним стоит единый контракт. Со временем вы заметите интересную закономерность: чем опытнее становится разработчик, тем реже он пишет явные циклы. Многие задачи, которые новичок решает циклом с накоплением результата, элегантнее выражаются через map, filter и reduce из следующего урока. Циклы остаются незаменимы там, где есть побочные эффекты или сложное управление потоком с break и continue, но привычка спрашивать себя «а нельзя ли это выразить декларативно?» — важный шаг к зрелому, читаемому коду в стиле SwiftUI.