Цикл C# - break vs. continue
В цикле C# (не стесняйтесь отвечать для других языков), какая разница между break и continue как средством выхода из структуры цикла и перехода к следующей итерации?
Пример:
foreach (DataRow row in myTable.Rows)
{
if (someConditionEvalsToTrue)
{
break; //what's the difference between this and continue ?
//continue;
}
}
Ответов (15)15
break
полностью выйдет из цикла, continue
просто пропустит текущую итерацию.
Например:
for (int i = 0; i < 10; i++) {
if (i == 0) {
break;
}
DoSomeThingWith(i);
}
Разрыв вызовет выход из цикла на первой итерации - DoSomeThingWith
никогда не будет выполнен. Это здесь:
for (int i = 0; i < 10; i++) {
if(i == 0) {
continue;
}
DoSomeThingWith(i);
}
Не будет выполняться DoSomeThingWith
для i = 0
, но цикл будет продолжаться и DoSomeThingWith
будет выполняться для i = 1
к i = 9
.
Чтобы полностью выйти из цикла foreach, используется break ;
Для перехода к следующей итерации цикла используется continue ;
Разрыв полезен, если вы просматриваете коллекцию объектов (например, строки в таблице данных) и ищете конкретное совпадение, когда вы найдете это совпадение, нет необходимости продолжать просмотр оставшихся строк, поэтому вы хотите разорвать из.
Продолжить полезно, когда вы выполнили то, что вам нужно, в итерации цикла. Обычно вы должны продолжить после if .
На примере
foreach(var i in Enumerable.Range(1,3))
{
Console.WriteLine(i);
}
Печатает 1, 2, 3 (на отдельных строках).
Добавить условие разрыва при i = 2
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
break;
Console.WriteLine(i);
}
Теперь цикл печатает 1 и останавливается.
Замените разрыв продолжением.
foreach(var i in Enumerable.Range(1,3))
{
if (i == 2)
continue;
Console.WriteLine(i);
}
Теперь зацикливаем отпечатки 1 и 3 (пропуская 2).
Таким образом, break
цикл останавливается, а continue
выполняется переход к следующей итерации.
Раньше я всегда не понимал, следует ли мне использовать паузу или продолжить. Вот что мне помогает запомнить:
Когда использовать break vs continue?
- Перерыв - это как расставание. Грустно, вы, ребята, расстаетесь. Цикл завершен.
- Продолжить - означает, что сегодня вы дадите отдохнуть, а завтра во всем разберетесь (т.е. пропустите текущую итерацию)!
Многим людям не нравится break
и continue
. Последняя жалоба, которую я видел на них, была в JavaScript: The Good Parts от Дугласа Крокфорда. Но я считаю , что иногда используя один из них действительно упрощает вещи, особенно если ваш язык не включать в себя do-while
или do-until
стиль цикла.
Я обычно использую break
в циклах, которые ищут что-то в списке. После того, как вы нашли, нет смысла продолжать, так что вы можете уйти.
Я использую, continue
когда что-то делаю с большинством элементов списка, но все же хочу пропустить некоторые.
Это break
утверждение также может пригодиться при опросе кого-то или чего-то действительного ответа. Вместо того:
Ask a question
While the answer is invalid:
Ask the question
Вы можете устранить дублирование и использовать:
While True:
Ask a question
If the answer is valid:
break
do-until
Цикл , который я упоминал ранее это более элегантное решение для этой конкретной проблемы:
Do:
Ask a question
Until the answer is valid
Никакого дублирования, да и не break
нужно.
К сожалению, Ruby немного отличается. PS: Моя память немного туманна по этому поводу, поэтому извиняюсь, если я ошибаюсь
вместо break / continue у него есть break / next, которые ведут себя одинаково с точки зрения циклов.
Циклы (как и все остальное) являются выражениями и «возвращают» последнее, что они сделали. В большинстве случаев получение возвращаемого значения из цикла бессмысленно, поэтому все просто делают это
a = 5
while a < 10
a + 1
end
Однако вы можете сделать это
a = 5
b = while a < 10
a + 1
end # b is now 10
ОДНАКО большая часть кода Ruby «эмулирует» цикл с помощью блока. Канонический пример:
10.times do |x|
puts x
end
Поскольку люди гораздо чаще хотят что-то делать с результатом блока, именно здесь это становится беспорядочным. break / next означают разные вещи в контексте блока.
break выскочит из кода, который вызвал блок
next пропустит остальную часть кода в блоке и «вернет» то, что вы укажете, вызывающей стороне блока. Без примеров это не имеет смысла.
def timesten
10.times{ |t| puts yield t }
end
timesten do |x|
x * 2
end
# will print
2
4
6
8 ... and so on
timesten do |x|
break
x * 2
end
# won't print anything. The break jumps out of the timesten function entirely, and the call to `puts` inside it gets skipped
timesten do |x|
break 5
x * 2
end
# This is the same as above. it's "returning" 5, but nobody is catching it. If you did a = timesten... then a would get assigned to 5
timesten do |x|
next 5
x * 2
end
# this would print
5
5
5 ... and so on, because 'next 5' skips the 'x * 2' and 'returns' 5.
Так что да. Ruby прекрасен, но у него есть несколько ужасных угловых моментов. Это второй худший вариант, который я видел за годы его использования :-)
break заставляет счетчик программы выскакивать за пределы самого внутреннего цикла
for(i = 0; i < 10; i++)
{
if(i == 2)
break;
}
Работает так
for(i = 0; i < 10; i++)
{
if(i == 2)
goto BREAK;
}
BREAK:;
continue - переход к концу цикла. В цикле for continue переходит к выражению приращения.
for(i = 0; i < 10; i++)
{
if(i == 2)
continue;
printf("%d", i);
}
Работает так
for(i = 0; i < 10; i++)
{
if(i == 2)
goto CONTINUE;
printf("%d", i);
CONTINUE:;
}
Позвольте мне заявить очевидное: обратите внимание, что добавление ни break, ни continue, не возобновит вашу программу; т.е. я поймал определенную ошибку, затем, зарегистрировав ее, я хотел возобновить обработку, и между следующей строкой было больше задач кода, поэтому я просто позволил ей провалиться.
Все дали очень хорошее объяснение. Я все еще публикую свой ответ, чтобы привести пример, если это может помочь.
// break statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
break; // It will force to come out from the loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Вот результат:
0 [напечатано] 1 [напечатано] 2 [напечатано]
Таким образом, 3 [Напечатано] и 4 [Напечатано] не будут отображаться, поскольку есть разрыв, когда i == 3
//continue statement
for (int i = 0; i < 5; i++) {
if (i == 3) {
continue; // It will take the control to start point of loop
}
lblDisplay.Text = lblDisplay.Text + i + "[Printed] ";
}
Вот результат:
0 [напечатано] 1 [напечатано] 2 [напечатано] 4 [напечатано]
Таким образом, 3 [Printed] не будет отображаться, так как есть continue, когда i == 3