Default как первый параметр в инструкции switch?

Я тестировал это, и он отлично работает, но он выглядит... странным... для меня. Должен ли я быть обеспокоен тем, что это нестандартная форма, которая будет удалена в будущей версии 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. почему default: падает до первого случая, а также устанавливает $kind)

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

Ответы

Ответ 1

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

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;

}

Ответ 2

Если кто-нибудь найдет эту страницу через 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"; или любые другие определенные случаи, он просто напечатает цвет.

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

Ответ 3

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

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;
}

Ответ 4

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

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

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

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

Ответ 5

Я лично предпочитаю делать

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 already set as 'kind1', but that doesn't make any difference to the code.
        // Do some stuff for kind 1 here
        break;

}

Ответ 6

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

Ответ 7

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

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

Ответ 8

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

Например:

$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
}

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

Ответ 9

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

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

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

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

Серьезно, почему вы хотели бы это сделать, это умудряет мой разум, но на самом деле это демонстрирует, насколько далеко может переключаться режим /case от шаблонов 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... но если вы это сделаете, и мне придется отлаживать ваш код позже, когда вы написали все это так... Пусть Линус Торвальдс пощадит вашу душу.