Почему `switch` считается циклической структурой для целей` continue`?
Я просто получил бит, предположив следующее:
foreach ($arr as $key => $value) {
switch($key) {
// ... some other cases
default:
continue;
// ^== assumption: move on to the next iteration of the foreach
// actual PHP: treat this continue just like a break
}
// ...
}
Но на самом деле, согласно документации для продолжения:
оператор switch считается структурой цикла для продолжения.
Есть ли причина для этого выбора со стороны разработчиков языка PHP? Насколько я могу судить, switch
не является структурой управления циклом, поэтому зачем относиться к ней как к одному в этом случае?
Ответы
Ответ 1
Я думаю, что вы не найдете реальной причины для этого поведения.
Единственная реальная мотивация этого поведения, вероятно, заключалась в том, что реализация switch
, как если бы это была структура цикла, позволяет PHP повторно использовать существующие семантики циклов break
и continue
вместо переопределения специальной версии для switch
.
Или выразить это более позитивно: это для согласованности.
Ответ 2
Лучшее объяснение, о котором я могу думать, заключается в том, что PHP считает его циклической структурой, поэтому он подходит для модели того, что использует continue
и break
. Документация switch
не проливает больше света на нее, кроме
Обратите внимание, что в отличие от некоторых других языков оператор continue применяется к коммутатору и действует подобно break. Если у вас есть переключатель внутри цикла и вы хотите продолжить следующую итерацию внешнего цикла, используйте continue 2.
Возможно, это потому, что, подобно циклу, он останавливает выполнение остальной части кода в своей структуре.
Однако, когда вы используете несколько уровней, эти два ведут себя совершенно по-другому:
continue
без уровня
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
continue;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//Finished with 2
//3
//Finished with 3
//4
//Finished with 4
continue
с уровнем
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
continue 2;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//3
//Finished with 3
//4
//Finished with 4
break
без уровня
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
break;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
//Finished with 2
//3
//Finished with 3
//4
//Finished with 4
break
с уровнем
<?php
for($i=0;$i<5;$i++) {
switch($i) {
case 2:
break 2;
default:
echo $i, "\n";
}
echo "Finished with {$i}\n";
}
//0
//Finished with 0
//1
//Finished with 1
Ответ 3
Насколько я могу судить, switch
не является структурой управления циклом, поэтому зачем относиться к ней как к одному в этом случае?
Существует ли одна итерация не как цикл? То же самое относится к while
внутри foreach
, например, только однократно:
foreach (range(1,2) as $value)
{
$i = 0;
while (!$i++)
{
continue;
}
echo $value, "\n";
}
Он также выполняет эхо-значения вместо continue
цикла foreach
; Это связано с while
.
Если ваше ожидание состоит в том, что switch
похоже на if
(а это не так), вы можете не ожидать такого поведения continue
, но я уверен, что вы ожидаете его while
.
Но если вы действительно думаете, что if
как switch
, то как break
работает иначе, чем continue
?
Итак, я не буду говорить, что это не так, просто switch
- это структура управления, имеющая одежду петли. И поскольку мы обычно используем break
(который вы ожидаете работать), поведение continue
не так хорошо известно. И это все. Или почему вы ожидаете, что continue
не будет работать как break
в switch
?
Таким образом, причина может заключаться в выравнивании break
и continue
.