break и continue
Вернёмся на беговую дорожку. До сих пор бегун останавливался, только когда кончались круги или условие становилось ложным. Но бывает, что цель достигнута посреди дистанции и бегать дальше незачем. Тогда бегун сходит с дорожки сразу.
Цикл, который что-то ищет, ведёт себя так же: найдя нужное, он должен остановиться. Инструкция break завершает цикл сразу. Эта программа ищет первое число больше 50, которое делится на 7:
for n in 51...100 {
if n % 7 == 0 {
print(n) // 56
break
}
}Два способа изменить ход цикла
break и continue работают в любом цикле: в for-in, while и repeat-while.
break
break — бегун сходит с дистанции. Строки тела ниже break не выполняются, новых итераций не будет, и программа продолжается со строки после цикла.
Разберём пример по итерациям:
- Для
nот51до55остаток от деления на7не равен нулю, и цикл идёт дальше. - При
n, равной56, условие истинно, и программа печатает56. breakзавершает цикл, и числа от57до100не проверяются.
break стоит внутри if, но завершает весь цикл, а не только if.
continue
continue — бегун срезает остаток текущего круга и сразу выходит на следующий. Цикл не заканчивается: for-in берёт следующее значение, а while снова проверяет условие, и тело начинается заново.
for n in 1...6 {
if n % 3 == 0 {
continue
}
print(n, terminator: " ") // 1 2 4 5
}Числа 3 и 6 делятся на 3, поэтому для них continue пропускает print. Если заменить continue на break, программа напечатает только 1 2: цикл закончится при n, равной 3.
Здесь картинка с бегуном неточна: бегун решает сам, когда сойти с дорожки. break и continue срабатывают, только когда выполнение дошло до их строки, поэтому обычно их ставят внутри if.
Вложенные циклы
Цикл внутри другого цикла называют вложенным. На дорожке это тренировка из нескольких подходов: в каждом подходе бегун пробегает свои круги. На каждой итерации внешнего цикла внутренний проходит все свои итерации заново.
Так перебирают пары чисел. Эта программа ищет пары a и b от 1 до 3, сумма которых равна 5:
for a in 1...3 {
for b in 1...3 {
if a + b == 5 {
print(a, b, terminator: "; ") // 2 3; 3 2;
break
}
}
}Разберём, что делает break:
- При
a, равной1, ни одна сумма не равна5, и внутренний цикл проходит все три итерации. - При
a, равной2, сумма2 + 3равна5: программа печатает пару, иbreakзавершает внутренний цикл. - Внешний цикл продолжает работу, и при
a, равной3, находится пара3 2.
break завершает только тот цикл, в теле которого стоит. Здесь это внутренний цикл. Подход закончился, но тренировка идёт дальше.
break с меткой
А если нужна только первая пара? Тогда выйти надо сразу из обоих циклов. Для этого внешнему циклу дают метку — имя с двоеточием перед словом for: search: for a in 1...3. Имя метки придумывают сами: search, outer или любое другое. Инструкция break search завершает цикл с этой меткой вместе со всеми циклами внутри него.
Это не метка аргумента из урока про print. Та стоит перед значением при вызове функции, а метка цикла стоит перед самим циклом и даёт ему имя.
Нажмите «Следующий шаг» и следите за константами a и b: после break search исчезают обе, а итерации с a, равной 3, не будет.
1search: for a in 1...3 {2 for b in 1...3 {3 if a + b == 5 {4 print("found", a, b)5 break search6 }7 }8}9print("done")
Внешний цикл начинает первую итерацию, и константа a равна 1.
Обычный break заканчивает подход, а break с меткой — всю тренировку. С меткой работает и continue: continue search сразу переходит к следующей итерации внешнего цикла.
На собеседовании часто спрашивают, как выйти сразу из двух вложенных циклов. Ответ: поставить метку на внешний цикл и написать break с этой меткой.
Частая ошибка
break написали внутри switch, который стоит в цикле:
for n in 1...5 {
switch n {
case 3:
break // ✗
default:
print(n, terminator: " ")
}
}Хотели остановить цикл на тройке, а программа печатает 1 2 4 5. Внутри switch обычный break выходит только из switch, как в пустом case, и цикл идёт дальше. Поставьте на цикл метку и выйдите по ней: с numbers: for n in 1...5 и break numbers программа напечатает 1 2.
Главное
breakсразу завершает цикл, аcontinueпропускает остаток текущей итерации и переходит к следующей.- Во вложенных циклах обычный
breakзавершает только тот цикл, в теле которого стоит. breakс меткой внешнего цикла, напримерbreak search, выходит сразу из обоих циклов.- Внутри
switchобычныйbreakвыходит только изswitch, а цикл завершаетbreakс меткой.