Desde que tengo uso de razón, he evitado utilizar fallos en las sentencias switch. En realidad, no puedo recordar que alguna vez haya entrado en mi conciencia como una forma posible de hacer las cosas, ya que se me inculcó desde el principio que no era más que un error en la declaración de cambio. Sin embargo, hoy encontré un código que lo usa por diseño, lo que me hizo preguntarme de inmediato qué piensan todos en la comunidad sobre la falla de la declaración de cambio.
¿Es algo que un lenguaje de programación no debería permitir explícitamente (como lo hace C #, aunque proporciona una solución) o es una característica de cualquier lenguaje que sea lo suficientemente potente como para dejarlo en manos del programador?
Editar: No fui lo suficientemente específico para lo que quise decir con fallos. Yo uso mucho este tipo:
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something
break;
case 2:
case 3:
case 4:
// Do something
break;
}
Sin embargo, me preocupa algo como esto.
switch(m_loadAnimSubCt){
case 0:
case 1:
// Do something, but fall through to the other cases
// after doing it.
case 2:
case 3:
case 4:
// Do something else.
break;
}
De esta manera, siempre que el caso sea 0, 1, hará todo lo que esté en la instrucción de cambio. He visto esto por diseño y simplemente no sé si estoy de acuerdo en que las declaraciones de cambio deben usarse de esta manera. Creo que el primer ejemplo de código es muy útil y seguro. El segundo parece un poco peligroso.
fuente
Respuestas:
Puede depender de lo que considere fallido. Estoy de acuerdo con este tipo de cosas:
Pero si tiene una etiqueta de caso seguida de un código que pasa a otra etiqueta de caso, casi siempre lo consideraría malo. Quizás mover el código común a una función y llamar desde ambos lugares sería una mejor idea.
Y tenga en cuenta que utilizo la definición de "malvado" de las preguntas frecuentes de C ++
fuente
Es una espada de doble filo. A veces es muy útil, pero a menudo peligroso.
¿Cuándo es bueno? Cuando desee que 10 casos se procesen todos de la misma manera ...
La única regla que me gusta es que si alguna vez haces algo elegante en el que excluyes el descanso, necesitas un comentario claro / * FALLTHROUGH * / para indicar que esa era tu intención.
fuente
if(condition > 1 && condition <10) {condition = 1}; switch(...
guardar sus casos (para una apariencia clara) y todos pueden ver que realmente desea que esos casos desencadenen la misma acción.¿Has oído hablar del dispositivo de Duff ? Este es un gran ejemplo del uso de interruptores fallidos.
Es una función que se puede utilizar y se puede abusar de ella, como casi todas las funciones del idioma.
fuente
La caída es realmente útil, dependiendo de lo que esté haciendo. Considere esta forma ordenada y comprensible de organizar las opciones:
Imagínese hacer esto con if / else. Sería un desastre.
fuente
Puede ser muy útil algunas veces, pero en general, el comportamiento deseado no es una falla. Se debe permitir la caída, pero no implícita.
Un ejemplo, para actualizar versiones antiguas de algunos datos:
fuente
Me encantaría una sintaxis diferente para los fallbacks en los conmutadores, algo como, errr ..
Nota: Esto ya sería posible con enumeraciones, si declara todos los casos en su enumeración usando banderas, ¿verdad? Tampoco suena tan mal; los casos podrían (¿deberían?) muy bien ser ya parte de su enumeración.
¿Quizás este sería un buen caso (sin juego de palabras) para una interfaz fluida usando métodos de extensión? Algo como, errr ...
Aunque probablemente sea incluso menos legible: P
fuente
Como con cualquier cosa: si se usa con cuidado, puede ser una herramienta elegante.
Sin embargo, creo que los inconvenientes más que justifican no usarlo y finalmente no permitirlo más (C #). Entre los problemas están:
Buen uso de un interruptor / caso fallido:
Baaaaad uso de un interruptor / caso fallido :
Esto se puede reescribir usando construcciones if / else sin ninguna pérdida en mi opinión.
Mi última palabra: manténgase alejado de las etiquetas de caso fallidas como en el mal ejemplo, a menos que esté manteniendo un código heredado donde este estilo se usa y se comprende bien.
fuente
Es poderoso y peligroso. El mayor problema con la caída es que no es explícito. Por ejemplo, si se encuentra con un código editado con frecuencia que tiene un interruptor con fallos, ¿cómo sabe que es intencional y no un error?
Donde sea que lo use, me aseguro de que esté correctamente comentado:
fuente
El uso de fallos como en su primer ejemplo está claramente bien, y no lo consideraría un fallo real.
El segundo ejemplo es peligroso y (si no se comenta extensamente) no es obvio. Enseño a mis alumnos a no usar tales construcciones a menos que consideren que vale la pena dedicarle un bloque de comentarios, que describe que esto es una falla intencional y por qué esta solución es mejor que las alternativas. Esto desalienta el uso descuidado, pero aún lo permite en los casos en que se usa con ventaja.
Esto es más o menos equivalente a lo que hicimos en proyectos espaciales cuando alguien quería violar el estándar de codificación: tenía que solicitar la dispensa (y me llamaron para asesorar sobre el fallo).
fuente
No me gusta que mis
switch
declaraciones fracasen, es demasiado propenso a errores y difícil de leer. La única excepción es cuando variascase
declaraciones hacen exactamente lo mismo.Si hay algún código común que varias ramas de una declaración de cambio quieran usar, lo extraigo en una función común separada que se puede llamar en cualquier rama.
fuente
En algunos casos, el uso de fallos es un acto de pereza por parte del programador; podrían usar una serie de || declaraciones, por ejemplo, pero en su lugar utilizan una serie de casos de cambio 'catch-all'.
Dicho esto, los he encontrado especialmente útiles cuando sé que eventualmente voy a necesitar las opciones de todos modos (por ejemplo, en una respuesta de menú), pero aún no he implementado todas las opciones. Del mismo modo, si está fallando tanto para 'a' como para 'A', me parece mucho más limpio usar el interruptor faltante que una declaración if compuesta.
Probablemente sea una cuestión de estilo y de cómo piensan los programadores, pero generalmente no me gusta eliminar componentes de un lenguaje en nombre de la 'seguridad', razón por la cual tiendo más hacia C y sus variantes / descendientes que, digamos, Java. Me gusta ser capaz de jugar con punteros y cosas por el estilo, incluso cuando no tengo "motivos" para hacerlo.
fuente
Fall-through debe usarse solo cuando se usa como una tabla de salto en un bloque de código. Si hay alguna parte del código con una ruptura incondicional antes de más casos, todos los grupos de casos deben terminar de esa manera.
Cualquier otra cosa es "malvada".
fuente