Romper en caso predeterminado en el interruptor

88

Estoy un poco desconcertado cuando o no incluir breakdespués del último caso, a menudo default.

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}

breakEl único propósito es, en mi opinión, evitar que el código se ejecute en el resto del switchcaso.

¿Entonces se considera más lógico tener un breakúltimo debido a la consistencia u omitirlo debido a la breakaplicación de ningún uso funcional? Ambos son lógicos de diferentes maneras en mi opinión.

Esto podría compararse hasta cierto punto con terminar un .phparchivo con ?>. Nunca termino ?>principalmente debido al riesgo de generar espacios en blanco, pero uno podría argumentar que sería lógico terminar con el archivo.

Robin Castlin
fuente

Respuestas:

144

breakno es técnicamente necesario después de la última alternativa (lo cual, ten en cuenta, no tiene que serlo default: es perfectamente legal y, a veces, incluso útil poner la defaultrama primero); si su código cae hasta el final de la switchdeclaración o breaksal final de su última rama tiene el mismo resultado.

Sin embargo, todavía terminaría cada rama, incluida la última, con una declaración returno break, por tres razones:

  1. Refactorabilidad. Si todas sus ramas terminan con breako return, puede reordenarlas sin cambiar el significado. Esto hace que sea menos probable que tal reordenamiento introduzca una regresión.
  2. Consistencia y menos sorpresa. La consistencia dice que sus ramas deben terminar consistentemente, a menos que en realidad tengan un significado diferente. El Principio de Menos Sorpresa dicta que cosas similares deberían verse similares. Terminar la última rama de un switchbloque exactamente como las anteriores cumple ambas, lo que facilita la lectura y la comprensión. Si deja de lado lo explícito break, la última rama será ópticamente diferente (lo cual es especialmente importante para un escaneo rápido), y para ver que realmente no es diferente, el lector tiene que descender al nivel esencial de leer declaraciones individuales .
  3. Protegiéndote a ti mismo. Si tiene la costumbre de terminar todas sus switchramas con un break, se volverá automático después de un tiempo, y será menos probable que lo olvide accidentalmente donde importa. Capacitarse para esperar el breakfinal de cada rama también ayuda a detectar las breakdeclaraciones que faltan , lo cual es excelente para la depuración y la resolución de problemas.
tdammers
fuente
Gracias por su comprensión en esto! El breakúltimo caso también :)
Robin Castlin
77
En C #, break(u otra declaración de flujo de control que sale de case) es técnicamente necesaria después de la última alternativa.
dan04
3
@ dan04: sí, buen punto. C # es una excepción aquí, y probablemente se deba a que los diseñadores de idiomas sabían sobre los problemas con la switchfalla en los idiomas existentes y querían evitarlos. Las reglas que C # impone coinciden bastante con las recomendaciones de mi respuesta.
tdammers
¿De qué idioma estás hablando específicamente? ¿C? C ++? C#? ¿Java? PHP?
svick
2
Un buen compilador trataría el final breakcomo un NO-OP en lugar de generar un jmpa la siguiente instrucción, ¿correcto?
Nathan Osman
11

Dada la ambigüedad que existe en torno al uso de switch-caseen la mayoría de los idiomas, al usarlo, sugeriría siempre usar una breakdeclaración, excepto cuando es explícitamente y por diseño no deseado .

En parte, esto se debe a que cada casellamada se ve igual, lo que en mi opinión mejoraría la legibilidad. Pero también significa que si alguien (incluso usted) elige insertar un casedespués del último en una etapa posterior, no necesita preocuparse por verificar el bloqueo anterior, lo que podría ayudar a reducir errores al agregar nuevo código.


fuente
77
Cuando quiero que un caso pase al siguiente (y no es el caso degenerado de case foo: case bar: ...) pongo un comentario explícito en el sentido de que quiero que ocurra el fracaso. Lo hace mucho más claro.
Donal Fellows
3
Sí, como un simple comentario // no breaken lugar debreak;
Pacerier
O un [[fallthrough]]atributo en el caso de C ++.
Ruslan
1

No es breaknecesario después del último caso. Uso la palabra " último " (no predeterminado ) porque no es necesario el caso predeterminado es el último caso.

switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}

Y sabemos que a break es necesario entre dos cases consecutivos . A veces, uso if(a!=0)mi código para mayor legibilidad cuando otros refieren mi código. Puedo elegir usar if(a), eso sería una cuestión de mi elección

Suvarna Pattayil
fuente
55
Para mí, eso significaría un "uso siempre de descanso", en caso de que algún programador agregue un nuevo caseal final switchsin verificar que breakexistió (sería culpa del programador, pero aún mejor estar seguro, si por alguna razón, porque podrías ser ese programador en 6 meses-)
SJuan76
@ SJuan76 Sí, estoy de acuerdo, es mejor prevenir que curar, si desea mantener una protección para errores futuros, debe incluir uno al final.
Suvarna Pattayil
1
Con ese argumento en mente, también podría argumentar que siempre tiene , al final de las matrices en caso de que se inserte un nuevo valor. Sin embargo, eso rompe algunos códigos y generalmente se ve feo :)
Robin Castlin
1
@Robin Poner una coma es diferente. Si no está allí y alguien agrega un nuevo valor a una matriz, obtendrá un error de compilación. Sin embargo, no habrá error de compilación si la declaración de caso anterior no tiene un descanso, por lo que sería posible que esto se omita y cause errores en tiempo de ejecución.
Keith Miller
@RobinCastlin Siempre que el idioma le permita poner un ,. En caso, defaultfue diseñado para ser el último caso. Tal vez el lenguaje consideraría un breakdespués como un error. Suponiendo que breakse permitiera como diferenciador SOLO entre dos casos.
Suvarna Pattayil