¿Es necesario agregar el caso predeterminado al usar los casos de cambio?

39

Durante una revisión reciente del código me pidieron que pusiera default en todos los archivos donde se use el bloque switch , incluso si no hay nada que hacer en default . Eso significa que tengo que poner el caso default y no escribir nada en él.

¿Es esto lo correcto? ¿Para qué serviría?

    
pregunta Ankit 04.01.2013 - 06:57

8 respuestas

30

Parece que hay tres casos en los que no es necesaria una declaración default :

  1. no quedan otros casos, porque hay un conjunto limitado de valores que ingresan el switch case . Pero esto podría cambiar con el tiempo (intencional o accidentalmente), y sería bueno tener un default case si algo cambia _ podría registrar o advertir al usuario sobre un valor incorrecto.

  2. usted sabe cómo y dónde se usará el switch case y qué valores lo ingresarán. De nuevo, esto podría cambiar y podría ser necesario un procesamiento adicional.

  3. otros casos no necesitan ningún procesamiento especial. Si este es el caso, creo que se le pide que agregue un default case , porque es un estilo de codificación aceptado, y hace que su código sea más legible.

Los dos primeros casos se basan en suposiciones. Por lo tanto (suponiendo que trabaje en un equipo no tan pequeño ya que tiene revisiones de código regulares), no puede permitirse hacer esas suposiciones. No sabe quién trabajará con su código o hará llamadas a funciones / métodos de invocación en su código. Del mismo modo, es posible que necesite trabajar con el código de otra persona. Tener el mismo estilo de codificación hará que sea más fácil tratar con el código de alguien (incluido el suyo).

    
respondido por el superM 04.01.2013 - 07:20
28
  

¿Es esto lo que hay que hacer? ¿Para qué serviría?

No es raro que los estándares de codificación de la empresa requieran un caso predeterminado para todas las declaraciones switch . Una de las razones es que facilita que los lectores encuentren el final del switch . Otra razón, probablemente mejor, es que te hace pensar por un segundo lo que debería hacer tu código cuando la condición no coincide con tus expectativas. Independientemente de la razón del requisito, si se trata de un estándar de la empresa, debe seguirlo a menos que haya una razón hermética para no hacerlo.

Si cree que su switch incluye casos para cada condición posible, entonces una buena cosa es poner una declaración assert en el caso predeterminado. De esa manera, cuando alguien cambie el código y agregue inadvertidamente una condición que su switch no cubra, alcanzarán el assert y se darán cuenta de que deben abordar esa parte del código.

Si su switch solo cubre algunas de las posibles condiciones, pero no se debe hacer nada especial para los demás, puede dejar el caso predeterminado vacío. Es una buena idea agregar un comentario en ese caso para indicar que el caso predeterminado está intencionalmente vacío porque las condiciones que lo afectan no necesitan ningún trabajo por hacer.

    
respondido por el Caleb 04.01.2013 - 07:31
12

Si "cambia" en el tipo de enumeración puro, es peligroso tener un repliegue predeterminado. Cuando luego agregue valores al tipo de enumeración, el compilador resaltará los interruptores con los nuevos valores no cubiertos. Si tiene una cláusula predeterminada allí, el compilador permanecerá en silencio y es posible que lo pierda.

    
respondido por el Artur 04.01.2013 - 08:24
9

En muchos aspectos, esta pregunta es la misma que la pregunta frecuente ¿Necesito una cláusula else al final de una escalera if / else if que cubre todas las opciones .

La respuesta es, sintácticamente hablando, no, no lo haces. Pero hay un sin embargo ...

Una cláusula default puede estar ahí por (al menos) dos razones:

  1. Como manejador de errores, seguro, ¡Nunca debería llegar aquí! es un reclamo que se puede hacer, pero ¿Qué pasa si lo hace? Corrupción de datos, o incluso peor, ninguna validación de datos es una ruta para el fallo del programa si no se atrapa correctamente. En este caso, ¡no debería ser una cláusula vacía!
  2. Diseño / Cobertura de código: incluso en la forma más simple de un diagrama de flujo, hay dos rutas desde una declaración if, y siempre un otherwise desde un caso. No hay ninguna razón para no incluirlos en el código fuente.

Mi filosofía es siempre bastante simple: evalúe el peor de los casos de las dos opciones y vaya por el más seguro. En el caso de una cláusula else o default vacía, las opciones para el peor de los casos son:

  • Inclúyalos: tres o cuatro líneas adicionales de código "redundante".
  • No los incluya: los datos falsos o una condición inesperada no se encuentran atrapados, lo que podría provocar un fallo en el programa.

¿Sobredramático? Tal vez ... pero luego mi software tiene el potencial de matar gente si falla. Prefiero no correr ese riesgo.

Como nota aparte, las directrices de MISRA-C {ver el perfil para afiliación} recomienda una cláusula default para cada switch

    
respondido por el Andrew 04.01.2013 - 08:05
6

Java no lo obliga a tener una declaración "predeterminada", pero es una buena práctica tenerla todo el tiempo, incluso si es posible que no se llegue al código (ahora mismo). Aquí hay algunas razones:

Al tener una cláusula predeterminada inalcanzable, le muestra al lector de su código que ha considerado los valores y sabe lo que está haciendo. También permite cambios futuros, por ejemplo: se agrega un nuevo valor de enumeración, el interruptor no debe ignorar silenciosamente el nuevo valor; en lugar de eso, puedes lanzar una Excepción o hacer otra cosa.

Para capturar un valor inesperado (en caso de que no esté activando una enumeración) que se haya pasado, podría ser mayor o menor de lo que esperaba, por ejemplo.

Para manejar acciones 'predeterminadas' - donde los conmutadores son para un comportamiento especial. Por ejemplo, una variable puede declararse fuera del conmutador pero no inicializarse y cada caso lo inicializa en algo diferente. En este caso, el valor predeterminado podría inicializarlo a un valor predeterminado, por lo que el código inmediatamente después del cambio no produce un error / lanza una excepción.

Incluso si decide no poner nada en el valor predeterminado (sin excepciones, registro, etc.), incluso un comentario que diga que ha considerado que el hecho de que nunca ocurrirá puede ayudar a la legibilidad de su código; pero eso se reduce a las preferencias personales.

    
respondido por el Deco 04.01.2013 - 07:19
2

También agregaría que depende de la filosofía del idioma que esté utilizando. En Erlang, por ejemplo, donde es un enfoque común para 'dejar que se bloquee', no definiría un caso predeterminado, pero permitiría que su declaración case genere un error si se produce una situación que no fue atendida.

    
respondido por el Rodrigue 04.01.2013 - 18:06
0

Siempre debe tener un valor predeterminado a menos que haya cubierto todos los casos de forma demostrable y permanente. No cuesta nada, y es un seguro contra fallas para mantener su declaración de cambio en un programa en evolución.

Si está realmente seguro de que no le importa ningún otro caso, el valor predeterminado es break: // no importa pero el valor predeterminado predeterminado debería ser algo como el predeterminado: lanzar un nuevo error ("valor inesperado");

Del mismo modo, nunca debe "pasar por alto" una construcción de caso no trivial sin agregar un comentario al efecto que pretende pasar. Java se equivocó en la etapa de diseño.

    
respondido por el ddyer 09.01.2013 - 19:12
-2

Considera

enum Gender
{
       MALE ,
       FEMALE ;
}

y

void run ( Gender g )
{
      switch ( g )
      {
           case MALE :
                 // code related to males
                 break ;
           default :
                 assert Gender . FEMALE . equals ( g ) ;
                 // code related to females
                 break ;
      }
}

Argumentaría que esto es superior a tener un caso MALE, un caso FEMALE y un caso predeterminado que produce una excepción.

Durante la fase de prueba, la computadora verificará si g es FEMENINO. Durante la producción, el cheque será omitido. (¡Sí, una microoptimización!)

Más importante aún, mantendrá su objetivo de cobertura de código del 100%. Si escribiste un caso predeterminado que lanza una excepción, ¿cómo lo probarías?

    
respondido por el emory 05.01.2013 - 04:12

Lea otras preguntas en las etiquetas