Короче говоря, вы должны выбрать ту версию, которую легче всего читать и поддерживать.
В немного более старые времена я знаю, что выход из цикла считался запретным (наравне с оператором goto). Циклы должны были нарушаться в состоянии цикла и больше нигде. Таким образом, цикл while был бы подходящим вариантом.
(Это, вероятно, удержание от сборки, где циклы - это, по сути, блок кода с оператором перехода go-to-the-begin-if-true в конце. Несколько операторов условного перехода в блоке делают его чрезвычайно трудно отладить, поэтому их нужно было избегать и объединять в одно целое.)
Мне кажется, что эта идея сегодня немного меняется, особенно с циклами foreach и управляемым миром; это действительно вопрос стиля сейчас. Разломы для найденных циклов, возможно, стали приемлемыми для многих, за исключением, конечно, некоторых пуристов. Обратите внимание, что я все же избегал бы использования break в цикле while, поскольку это может запутать состояние цикла и сделать его запутанным.
Если вы позволите мне использовать цикл foreach, я считаю, что приведенный ниже код будет много проще для чтения, чем его брат while:
bool isBaxterInMilwaukee;
foreach (var item in myArray)
{
if (item.name == "baxter" && item.location == "milwaukee")
{
isBaxterInMilwaukee = true;
barkTwice();
break;
}
}
Однако, по мере усложнения логики, вы можете рассмотреть заметный комментарий рядом с оператором break
, чтобы его не похоронили и было трудно найти.
Возможно, все это должно быть преобразовано в собственную функцию , которая не break
при обнаружении, но на самом деле return
s результат (не стесняйтесь использовать вместо этого версию for-loop ):
bool isBaxterInMilwaukee(Array myArray)
{
foreach (var item in myArray)
{
if (item.name == "baxter" && item.location == "milwaukee")
{
barkTwice();
return true;
}
}
return false;
}
Как указал Эско Луонтола, вероятно, было бы лучше перенести вызов на barkTwice()
вне этой функции, поскольку побочный эффект не очевиден из названия функции и не связан с поиском Бакстера в каждом случае. (Или добавьте логический параметр BarkTwiceIfFound
и измените строку на if(BarkTwiceIfFound) barkTwice();
, чтобы прояснить побочный эффект.)
Для записи, вы также можете выполнить проверку флага в цикле for без перерыва, но я чувствую, что это фактически ухудшает читабельность, потому что вы не ожидаете дополнительного условия в определении цикла for:
var i:int;
var isBaxterInMilwaukee:Boolean;
for (i = 0; !isBaxterInMilwaukee && i < arrayLen; i++)
{
if (myArray[i]["name"] == "baxter"
&& myArray[i]["location"] == "milwaukee")
{
isBaxterInMilwaukee = true;
barkTwice();
}
}
Вы также можете имитировать механику автоинкремента с помощью цикла while. Мне это не нравится по нескольким причинам - вам нужно инициализировать i
, чтобы он был на единицу меньше вашего реального начального значения, и в зависимости от того, как ваш компилятор закорачивает логику условия цикла, ваше значение i
на выход из цикла может отличаться. Тем не менее, это возможно, и для некоторых людей это может улучшить читаемость:
var i:int = -1;
var isBaxterInMilwaukee:Boolean;
while (!isBaxterInMilwaukee && ++i < arrayLen)
{
if (myArray[i]["name"] == "baxter"
&& myArray[i]["location"] == "milwaukee")
{
isBaxterInMilwaukee = true;
barkTwice();
}
}