2012-01-26 6 views
19

Ho appena po 'ottenuto assumendo la seguente:Perché un `switch` è considerato una struttura di loop ai fini di` 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 
    } 
    // ... 
} 

Ma in realtà, secondo il documentation for continue:

l'istruzione switch è considerata una struttura loop a fini di continuano.

C'è una ragione per questa scelta da parte dei progettisti di PHP? Per quanto ne so, switchnon è una struttura di controllo in loop, quindi perché trattarlo come uno in questo caso?

+17

Si dovrebbe evitare l'uso delle parole "motivo" e "progettazione" quando si parla di 'php';) –

+6

si può usare' continue 2' =) – cweinberger

+0

Ho intenzione di indovinare che trattare 'switch' come un loop la struttura fornisce una certa coerenza programmatica a come funzionano 'break' e' continue' per ** tutte ** le strutture di looping. – zzzzBov

risposta

3

penso che non troverete alcuna vera "ragione" per questo comportamento.

L'unica reale motivazione alla base di questo comportamento era probabilmente che l'attuazione switch come se si trattasse di una struttura loop consente di riutilizzare PHP esistente break e continue semantica di cicli al posto di reimplementare una versione speciale per switch.

O per esprimerlo in modo più positivo: è per coerenza.

+0

quindi, "erano pigri"? Ha senso, immagino: P – chesles

+0

L'espressione 'switch' viene valutata per ciascun caso (' case', 'default') fino al termine del ciclo (fine del blocco di codice o fino a' break', 'continue' o' return' è dato). – hakre

+0

@hakre non è vero. "In un'istruzione switch, la condizione viene valutata solo una volta e il risultato viene confrontato con ogni dichiarazione di caso" - http://www.php.net/manual/en/control-structures.switch.php – chesles

7

La spiegazione migliore che riesco a pensare è che PHP lo consideri una struttura ad anello in modo che si adatti al modello di qualcosa che utilizza continue e break. La documentazione switch non lasci molto ulteriore luce su di esso diverso

Si noti che a differenza di alcuni altri linguaggi, la continua affermazione vale per passare e agisce simile a rompere. Se hai un interruttore all'interno di un ciclo e desideri continuare con l'iterazione successiva del ciclo esterno, utilizza continua 2.

Quindi forse è perché, come un loop, interrompe l'esecuzione del resto del codice nella sua struttura.

Tuttavia, quando si utilizza un numero di livelli, questi due si comportano in modo diverso:

continue senza un livello

<?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 con un livello

<?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 senza un livello

<?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 con un livello

<?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 
-2

Per quanto ne so, switch non è una struttura di controllo a ciclo, quindi perché trattarlo come uno in questo caso?

Una iterazione non si qualifica come un loop? Stesso vale per while all'interno di un foreach per esempio che solo itera volta:

foreach (range(1,2) as $value) 
{ 
    $i = 0; 
    while (!$i++) 
    { 
     continue; 
    } 
    echo $value, "\n"; 
} 

Fa eco i valori così invece continue loop foreach; È relativo a while.

Se la vostra aspettativa è che switch è come if (che non è), allora non si potrebbe aspettare che il comportamento di continue, però io sono abbastanza sicuro per while te lo aspetti.

Ma se davvero pensa che if è come switch, quindi come poteva break lavoro diverso rispetto continue?

Quindi non dirò che è molto fuori uso, è solo che switch è una struttura di controllo con gli abiti di un ciclo. E come normalmente usiamo break (che ti aspetti di funzionare), il comportamento di continue non è così noto. E questo è tutto. O perché ti aspetti che continue non funzioni come break in un switch?

Quindi il motivo potrebbe essere avere break e continue allineati.

+0

La mia aspettativa * è * quell'interruttore è come una stringa di 'if' /' else if', che è, a meno che non mi sbagli. Alcune lingue che non hanno 'switch' (ad es. Python) dicono anche" usa if/elif invece di cambiare ". Quindi, come è il passaggio non come un se in PHP? – chesles

+0

"L'istruzione switch è simile a una serie di istruzioni IF sulla stessa espressione." - http://www.php.net/manual/en/control-structures.switch.php – chesles

+0

@chesles: Okay, è quello che pensavo (avendo l'interruttore in testa come se fosse) - quindi l'analogia è 'pausa 'e' continua' allora. Ti aspetti che funzionino allo stesso modo (come 'if' e' switch' per 'break' e' continue')? – hakre

Problemi correlati