Почему «switch» считается циклической структурой для «continue»? - PullRequest
19 голосов
/ 26 января 2012

Я только что получил, предположив следующее:

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 считается циклической структурой для целей continue .

Есть ли причина для такого выбора со стороны разработчиков языка PHP? Насколько я могу судить, switch не является циклической управляющей структурой, так зачем в этом случае рассматривать ее как единицу?

Ответы [ 3 ]

7 голосов
/ 27 января 2012

Лучшее объяснение, которое я могу придумать, заключается в том, что PHP считает это циклической структурой, поэтому она соответствует модели чего-то, что использует continue и break. Документация switch не проливает свет на это больше, чем

Обратите внимание, что в отличие от некоторых других языков, оператор continue применяется к switch и действует аналогично break. Если у вас есть переключатель внутри цикла и вы хотите перейти к следующей итерации внешнего цикла, используйте продолжить 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 голосов
/ 27 января 2012

Я думаю, вы не найдете никакой реальной "причины" для такого поведения.

Единственная реальная мотивация такого поведения, вероятно, заключалась в том, что реализация switch, как если бы она была цикличной структурой, позволяет PHP повторно использовать существующую семантику циклов break и continue вместо переопределения специальной версии для switch.

Или, если выразить это более позитивно: это для последовательности.

0 голосов
/ 27 января 2012

Насколько я могу судить, 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.

...