по умолчанию в качестве первого варианта в инструкции switch? - PullRequest
15 голосов
/ 07 августа 2009

Я проверил это, и оно отлично работает, но выглядит ... странно ... для меня. Должен ли я быть обеспокоен тем, что это нестандартная форма, которая будет удалена в будущей версии PHP, или что она может перестать работать? У меня всегда был случай по умолчанию в качестве последнего случая, а не первый случай ...

switch($kind)
{
    default:
        // The kind wasn't valid, set it to the default
        $kind = 'kind1';
        // and fall through:

    case 'kind1':
        // Do some stuff for kind 1 here
        break;

    case 'kind2':
        // do some stuff for kind2 here
        break;

    // [...]

    case 'kindn':
        // do some stuff for kindn here
        break;

}

// some more stuff that uses $kind here...

(В случае, если не очевидно, что я пытаюсь сделать, это убедиться, что $ kind действителен, то есть по умолчанию: case. Но коммутатор также выполняет некоторые операции, а затем $ kind также используется после коммутатора. почему по умолчанию: возвращается к первому случаю, а также устанавливает $ kind)

Предложения? Это нормальный / правильный синтаксис?

Ответы [ 9 ]

22 голосов
/ 07 августа 2009

Это необычная идиома, она вызывает небольшую паузу, когда вы ее читаете, момент «а?». Это работает, но большинство людей, вероятно, ожидают найти регистр по умолчанию в конце:

switch($kind)
{
    case 'kind2':
        // do some stuff for kind2 here
        break;

    // [...]

    case 'kindn':
        // do some stuff for kindn here
        break;

    case 'kind1':
    default: 
        // Assume kind1
        $kind = 'kind1';

        break;

}
9 голосов
/ 26 августа 2011

На случай, если кто-нибудь найдет эту страницу через Google, как я:

Мне было интересно то же самое, что и Джошу - так что ... Одна вещь - это стандарты, которые, я думаю, мы все должны усерднее придерживаться, но другая вещь - это хакерство (в некотором смысле: взломать каждую возможность).

Хотя это уродливо / странно / не нормально - это возможно, и ИМХО может быть полезно в некоторых редких случаях ...

Обратите внимание на следующее:

$color = "greenish";
//$color = "green";

switch($color) {
    default:
        echo "no colors were selected so the color is: ";
    case "red":
        echo "red<br />\n";
        break;
    case "blue":
        echo "blue<br />\n";
        break;
    case "green":
        echo "green<br />\n";
        break;
}

Если $color = "greenish"; код напечатает

цвета не выбраны, поэтому цвет красный

, а если $color = "green"; или любые другие определенные случаи, он просто напечатает цвет.

Он знает, что это не лучший пример, но вы понимаете;) Надеюсь, это кому-нибудь поможет.

4 голосов
/ 23 июля 2011

Это выглядит странно по той же причине, что

else {
   echo "lol";
}
if (1 == 1) {
   echo "bbq";
}

выглядело бы странно, если бы оно было действительным. Если бы только по этой причине я бы избежал этого.

Кроме того, вы знаете, что каждый раз, когда вы показываете кому-то код, вам придется объяснить, что сначала ставить случай default было преднамеренным; обычно это признак того, что это не очень хорошая идея.

4 голосов
/ 24 февраля 2010

Вот как я бы, вероятно, сделал это ... это просто на глаз и сохраняет функциональность.

switch($kind)
{
    case 'kind1': default :
        // Do some stuff for kind 1 here
        break;
    case 'kind2':
        // do some stuff for kind2 here
        break;
    case 'kindn':
        // do some stuff for kindn here
        break;
}
3 голосов
/ 07 августа 2009

Я бы лично предпочел сделать

switch($kind)
{
    case 'kind2':
        // do some stuff for kind2 here
        break;

    // [...]

    case 'kindn':
        // do some stuff for kindn here
        break;

    case 'kind1':
    default:
        $kind = 'kind1'; // Redundant if it's already set as 'kind1', but that doesn't make any difference to the code.
        // Do some stuff for kind 1 here
        break;

}
2 голосов
/ 10 октября 2013

Это может быть очень удобно для управления потоком, особенно если вы не разбиваете между делами.

Например:

$step = $_GET['skip_to_step'];
switch($step) {
    default:
    case 'step1':
        // do some stuff for step one
    case 'step2':
        // this follows on from step 1 or you can skip straight to it
}

Вы можете добавить дополнительное «если», или «умное», или «, чтобы установить $step по умолчанию на 'step1' перед запуском коммутатора, но это просто дополнительный код, снижающий читабельность.

2 голосов
/ 07 августа 2009

Поначалу я от этого болел, но это только потому, что мы не привыкли так смотреть.

Я бы посоветовал вам документально подтвердить это, поскольку некоторые могут назвать этот «хитрый» код. Нуб или какой-нибудь будущий сопровождающий может прийти и переместить его на дно, где им будет удобнее, и сломать побочный эффект, который имеет место наверху.

2 голосов
/ 07 августа 2009

Обычной практикой является определение опции по умолчанию в качестве последней опции. Но я не вижу ничего плохого в вашем решении (если в вашей компании нет предопределенной схемы для разметки вашего кода)

1 голос
/ 11 сентября 2015

Другие ответы дают хорошие примеры, просто для ясности ...

Случай (включая значение по умолчанию) не прекращается при его завершении, если вы не включите разрыв. Хотя переключатель часто сравнивают с последовательностью if elseif elseif и т. Д., Однако это не совсем так.

Короткая версия: SWITCH / CASE действует только как IF / ELSEIF / ELSE , если , вы включаете разрывы после каждого случая. SWITCH / CASE больше похож на серию операторов «if», в которых каждый из них имеет одинаковую проверку переменных с разными значениями, по которым он проверяется.

Длинная версия: Без учета перерыва каждый случай является «началом здесь», и различия во многих отношениях делают его ближе к GOTO без недостатков. Технически, если вы действительно ДЕЙСТВИТЕЛЬНО хотели (читай, были мазохистские кодеры, которые хотели по-настоящему бросить вызов себе), вы могли бы написать практически любые процедурные программы, используя только один внешний массив, цикл for и переключатель, вложенный внутрь.

Серьезно, почему вы хотели бы сделать это, уму непостижимо, но это действительно демонстрирует, насколько далеко переключатель / регистр может отклоняться от паттернов if / elseif, поэтому он здесь для вас по академическим причинам (но не делайте этого!) ...

$array = [];
$array['masterLoop'] = 1;
$for ($i = 0, $i < $array['masterLoop'], $i++ ){
    switch($array['goto']){
        default: 
        case 1: 
            PRINT: "Welcome to the program";
        case 2: 
            PRINT: "Please make a choice:";
        case 3:
            $array['choice']='';
            // Wait for some input variable and set choice to it.
        case 4: 
            $array['goto']=$array['choice'];
            $array['masterLoop']++;
    }
}

То, как этот код будет выполняться (после того, как вы настроили что-то для захвата и установки выбора), будет запускаться с

"Welcome to the program. Please make a choice."
<<user inputs 2>>
"Please make a choice."
<<user inputs 1>>
"Welcome to the program. Please make a choice."
<<user inputs 3>>
// program awaits user input
<<user inputs 4>>
// user triggers infinite loop

Итак ... вы можете использовать переключатели, чтобы вспомнить времена BASIC ... но если вы это сделаете, и я должен отладить ваш код позже, после того, как вы все это написали ... Пусть Линус Торвальдс помилует вашу душу.

...