1. Зачем управлять циклом
Когда вы только начинаете писать циклы, хочется, чтобы они были «честными»: for идёт до конца диапазона, while крутится, пока условие истинно, и всё максимально предсказуемо. И это правильный этап. Но довольно быстро вы встречаете жизненные ситуации, где «дойти до конца» не нужно — вы уже нашли ответ, вам достаточно первых данных, или пользователь попросил остановиться.
Вот здесь и появляются два ключевых инструмента управления потоком внутри цикла: break и continue. Они звучат как названия рок-групп (особенно break), но на деле это очень практичные команды.
Важно: break и continue — не «читерство» и не «грязный хак». Это нормальная часть языка, и в реальном Swift‑коде вы их будете видеть постоянно. Например, паттерн while true { ... if ... { break } } — вполне официальный стиль: цикл крутится «вечно», но имеет чёткое правило остановки через break.
2. break: выходим из цикла
break нужен, когда вы хотите немедленно завершить цикл, в котором он написан. То есть «прямо сейчас перестать повторять и перейти к коду после цикла». Это похоже на ситуацию, когда вы ищете ключи в кармане: нашли — и дальше карман проверять уже не надо.
Минимальный пример: досрочно остановить for
После этого подзаголовка будет очень простой пример, чтобы вы почувствовали механику. Не пытайтесь сразу искать в нём «пользу для человечества» — это тренировочная площадка, где мы наблюдаем поведение программы глазами.
let n = 10
for i in 1...n {
if i == 4 {
print("Нашли 4 — выходим")
break
}
print("i=\(i)")
}
print("После цикла")
Здесь цикл мог бы напечатать i=1 до i=10, но мы «рубим» его на условии i == 4. В результате диапазон i=5...10 уже не выполняется.
Типовой сценарий: поиск первого подходящего
Теперь подойдём ближе к реальности. Частая задача: найти первое число, которое подходит условию. Как только нашли — смысла продолжать нет. В таких случаях break превращает цикл из «проверю всё подряд» в «проверю, пока не найду».
let target = 21
var firstDivisor = 0
for d in 2...target {
if target % d == 0 {
firstDivisor = d
break
}
}
print("firstDivisor=\(firstDivisor)") // firstDivisor=3
Мы нашли делитель и остановились на первом же. Это и есть «ранний выход» — в хорошем смысле.
break в while: пока не скажу «стоп»
После этого подзаголовка важно поймать одну мысль: break особенно полезен там, где цикл может продолжаться неопределённо долго, потому что зависит от ввода пользователя. И тогда break становится явным «контрактом остановки» — вы пишете в коде, при каком событии цикл заканчивается.
var sum = 0
while true {
let line = readLine() ?? ""
if line == "stop" {
break
}
let value = Int(line) ?? 0
sum = sum + value
}
print("sum=\(sum)")
Это тот самый паттерн «вечный цикл + правило остановки». Важная деталь: правило остановки должно быть очевидным и находиться прямо рядом с чтением/логикой. Тогда такой код читается нормально и не вызывает ощущения «программа ушла в астрал». В Swift‑сообществе этот стиль вполне привычен.
3. continue: пропускаем итерацию и идём дальше
Если break — это «закрываем цикл целиком», то continue — это «пропускаем только текущую итерацию». Представьте очередь на кассе: человек перед вами забыл кошелёк и ушёл за ним — очередь не отменяется, просто этот человек временно «пропущен», а вы двигаетесь дальше.
continue делает две вещи одновременно: заканчивает текущую итерацию и прыгает к следующей (к следующему значению в for или к следующей проверке условия в while).
Минимальный пример: печатаем только нечётные
После этого подзаголовка пример будет максимально «школьный», но он идеально показывает механику: часть значений мы «отбрасываем», и код ниже continue на этой итерации не выполняется.
for i in 1...10 {
if i % 2 == 0 {
continue
}
print("odd=\(i)")
}
Все чётные числа «проскальзывают» мимо print.
Типовой сценарий: фильтрация в цикле
После этого подзаголовка мы применим continue к вводу пользователя — это более жизненно. Часто человек вводит пустую строку, случайно пробел, или вообще «что-то не то». И вместо того чтобы писать огромную вложенность if/else, удобнее сказать: «если мусор — пропусти итерацию и попроси ввод снова».
var count = 0
while true {
let line = readLine() ?? ""
if line == "stop" {
break
}
if line == "" {
continue
}
let value = Int(line) ?? 0
if value <= 0 {
continue
}
count = count + 1
print("accepted=\(value)") // accepted=...
}
print("count=\(count)")
Тут continue работает как «сито»: пустые строки и неположительные числа не участвуют в «нормальной» логике.
4. Таблица-памятка: break vs continue
В этом месте полезно притормозить и зафиксировать различия. Когда вы пишете программу, мозг часто путает «прервать итерацию» и «прервать цикл». Из-за этого появляются баги, которые выглядят как «почему оно не работает, я же написал continue?!».
| Команда | Что делает | Куда прыгаем дальше |
|---|---|---|
|
завершает весь ближайший цикл | к строке после цикла |
|
завершает текущую итерацию | к следующей итерации (или к проверке условия в while) |
Если вам нужно «закончить прямо сейчас и выйти наружу» — это break. Если нужно «пропустить текущий шаг и попробовать следующий» — это continue.
5. Мини‑проект: «Копилка расходов»
Сейчас мы соберём маленькую консольную программу, которую будем «выращивать» из нескольких примеров. Она простая, но полезная: пользователь вводит расходы (целые числа), программа считает сумму и количество принятых значений. Команда "stop" завершает ввод. Пустые строки и мусор мы игнорируем.
Важно: мы сознательно держимся в рамках того, что вы уже знаете. Никаких функций (func), никаких массивов, никакого switch. Только ввод, условия, циклы и аккуратные проверки.
Версия 1: только break по команде "stop"
После этого подзаголовка будет «скелет» программы: цикл чтения, выход по слову "stop", суммирование всего остального. Это самый простой вариант, он нужен, чтобы не смешивать сразу всё.
var total = 0
while true {
let line = readLine() ?? ""
if line == "stop" {
break
}
let value = Int(line) ?? 0
total = total + value
}
print("total=\(total)")
Да, здесь есть «слабое место»: если введут "hello", оно превратится в 0 и всё равно попадёт в сумму. Сейчас исправим.
Версия 2: добавляем continue как валидацию ввода
Сейчас сделаем поведение более человечным: пустые строки, нули и отрицательные числа не считаем расходами (представим, что пользователь ошибся). А ещё выведем подсказку, если ввод некорректный — но так, чтобы не усложнять код.
var total = 0
var acceptedCount = 0
while true {
let line = readLine() ?? ""
if line == "stop" {
break
}
if line == "" {
print("Пустая строка — пропускаю")
continue
}
let value = Int(line)
if value == nil {
print("Это не число — пропускаю")
continue
}
let amount = value ?? 0
if amount <= 0 {
print("Нужно положительное число — пропускаю")
continue
}
total = total + amount
acceptedCount = acceptedCount + 1
}
print("acceptedCount=\(acceptedCount)")
print("total=\(total)")
Обратите внимание на стиль: как только мы понимаем, что строка «плохая», мы делаем continue и не держим в голове огромную лестницу else if else if else.
6. Типовые паттерны, которые стоит узнавать
Сейчас будет серия маленьких сценариев. Каждый из них — как мини-кирпичик. По отдельности они выглядят простыми, но потом из них строятся вполне серьёзные программы.
Пока не введут корректно: repeat-while + continue
Здесь важно не устроить путаницу: continue работает и в repeat-while, но новичкам иногда сложно «поймать», что условие проверится после тела. Поэтому пример будет очень осторожный: мы делаем минимум логики и явно показываем, что происходит.
var number = 0
repeat {
let line = readLine() ?? ""
let value = Int(line) ?? 0
if value <= 0 {
print("Введите число > 0")
continue
}
number = value
} while number <= 0
print("number=\(number)")
Тут continue означает: «показали сообщение и пошли на следующий круг». А условие while number <= 0 всё равно проверится (потому что это repeat-while).
Показали "help" и вернулись к началу
Сейчас добавим в нашу «копилку расходов» маленькую команду "help". Это частая вещь в интерактивных программах: пользователь вводит слово-команду, программа печатает подсказку и продолжает цикл, не пытаясь превращать "help" в число.
var total = 0
while true {
let line = readLine() ?? ""
if line == "stop" {
break
}
if line == "help" {
print("Введите расход целым числом. stop — завершить.")
continue
}
let amount = Int(line) ?? 0
total = total + amount
}
print("total=\(total)")
Да, мы всё ещё не валидируем "hello" — это упрощённая версия ради паттерна. В реальной версии мы бы объединили "help" и проверки из предыдущего раздела.
Ограничение по условию: выходим, если достигли лимита
Сейчас пример про break, который встречается постоянно: мы копим сумму, но как только она стала слишком большой (или достигла цели) — выходим.
let goal = 1000
var total = 0
while true {
let line = readLine() ?? ""
if line == "stop" { break }
let amount = Int(line) ?? 0
if amount <= 0 { continue }
total = total + amount
print("total=\(total)")
if total >= goal {
print("Цель достигнута!")
break
}
}
7. Полезные нюансы и ментальные модели
Визуальная схема: как читать код с continue
После этого подзаголовка — маленькая блок-схема, чтобы мозг перестал воспринимать continue как «магическую телепортацию». На самом деле всё просто: если continue сработал — остальной код в теле цикла на этой итерации не выполняется.
псевдокод/схема:
flowchart TD
A[Начало итерации] --> B{Условие 'плохой ввод'?}
B -- да --> C[continue] --> D[Следующая итерация]
B -- нет --> E[Основная логика] --> F[Конец итерации] --> D
Такой рисунок полезно вспоминать, когда вам кажется: «я же увеличиваю сумму… почему она не увеличилась?» — очень часто ответ: «потому что перед этим сработал continue».
Нюанс читаемости: continue уменьшает вложенность
Сейчас важная инженерная мысль. Когда вы пишете код в стиле:
if good {
// много кода
}
и у вас пять проверок подряд, вы быстро получаете «пирамиду» из вложенных if. Читать это тяжело: взгляд постоянно ищет, где закрывается какой блок.
continue позволяет писать наоборот: «если плохо — пропусти», а «нормальная логика» остаётся на одном уровне вложенности. В Swift‑сообществе даже обсуждали, что некоторые синтаксические формы фильтрации в цикле по смыслу сводятся к continue (то есть «не подходит — пропускаем»).
Мы не будем использовать редкие синтаксические трюки, но идея полезная: continue — это инструмент, который делает код плоским и легче читаемым.
for + continue: пропуск мусора
Здесь мы вернёмся к for-in и покажем типовой сценарий: мы делаем фиксированное число повторов (например, 5 вводов), но часть вводов может оказаться некорректной. В этом случае continue позволяет «не засчитывать» некорректную итерацию? Осторожно: нет, continue не отменяет сам факт итерации for. Он просто пропускает код ниже.
Это важно: если вам нужно «сделать ровно 5 корректных вводов», то for может быть неудобен — тогда лучше while со счётчиком корректных значений. Но в рамках примера мы покажем именно поведение.
var total = 0
for _ in 0..<5 {
let line = readLine() ?? ""
let value = Int(line) ?? 0
if value <= 0 {
print("Не засчитываю")
continue
}
total = total + value
}
print("total=\(total)")
8. Типичные ошибки при работе с break и continue
Ошибка №1: ожидать, что continue завершит цикл целиком.
Это очень частая путаница: человек пишет continue, думая «всё, выходим», а программа продолжает спрашивать ввод. Так и должно быть: continue завершает только текущую итерацию. Если нужно выйти насовсем — используйте break.
Ошибка №2: писать важный код после continue и удивляться, что он не выполняется.
Если у вас внизу тела цикла стоит total = total + amount, а выше есть continue, то при срабатывании continue сумма не изменится. Это не баг языка — это ваш «ранний прыжок». Хороший приём — держать continue ближе к началу итерации, как фильтры/валидацию, а «главную логику» — ниже.
Ошибка №3: делать while true, но забывать про правило остановки.
Сам по себе while true не плох. Он плох, когда вы не оставили читателю понятного способа выйти. Если в теле цикла нет гарантированного условия break, программа превращается в бесконечную. В хороших примерах break всегда рядом с чтением ввода или проверкой ключевого условия.
Ошибка №4: пытаться “починить” неправильное условие в while с помощью break.
Иногда пишут условие цикла слишком сложно, а потом добавляют break, чтобы «как-то работало». Лучше наоборот: либо делайте простое условие while, либо честно используйте while true и одно-два ясных правила break. Если и условие сложное, и breakов много — код становится трудным для проверки глазами.
Ошибка №5: “тихий” некорректный ввод без сообщений.
Технически можно молча делать continue на плохом вводе, но новичку (и пользователю) потом сложно понять, что произошло: «я ввёл что-то, а программа как будто проигнорировала». Часто помогает хотя бы короткое сообщение print("Некорректный ввод"). Это не обязательно всегда, но на этапе обучения — почти спасательный круг.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ