A menudo, cuando escucho sobre la declaración de cambio, se pospone como una forma de reemplazar largas cadenas ... si no. Pero parece que cuando uso la instrucción switch estoy escribiendo más código del que estaría escribiendo si ... de lo contrario. También tiene otros problemas, como mantener todas las variables para todas las llamadas en el mismo ámbito .
Aquí hay un código que representa el flujo que normalmente escribo ( gracias a diam )
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
if (which == 0) {
comment = "You look so much better than usual.";
} else if (which == 1) {
comment = "Your work is up to its usual standards.";
} else if (which == 2) {
comment = "You're quite competent for so little experience.";
} else {
comment = "Oops -- something is wrong with this code.";
}
Luego quieren que reemplace eso con esto:
String comment; // The generated insult.
int which = (int)(Math.random() * 3); // Result is 0, 1, or 2.
switch (which) {
case 0:
comment = "You look so much better than usual.";
break;
case 1:
comment = "Your work is up to its usual standards.";
break;
case 2:
comment = "You're quite competent for so little experience.";
break;
default:
comment = "Oops -- something is wrong with this code.";
}
Parece mucho más código en una sintaxis mucho más incómoda. Pero, ¿hay realmente una ventaja al usar la instrucción switch?
Respuestas:
Para esta situación particular, me parece que ambas
if
ycase
son malas elecciones. Yo usaría una matriz simple:Como nota al margen, generalmente debe calcular el multiplicador en función del tamaño de la matriz en lugar de codificarlo
3
.En cuanto a cuando se le utilice un caso / interruptor, la diferencia de una cascada de
if
declaraciones (o al menos una gran diferencia) es queswitch
puede semiautomática optimización basándose en el número y la densidad de los valores, mientras que una cascada deif
declaraciones hojas del compilador con pocas opciones más que generar el código tal como lo has escrito, probando un valor tras otro hasta que encuentre una coincidencia. Con solo tres casos reales, eso no es una preocupación, pero con un número suficiente puede / podría ser significativo.fuente
case
declaración o una cascada deif
declaraciones adecuadas. La mayoría de las veces, son un sustituto (mediocre) de algún tipo de mapa / matriz, y es mejor usar uno de estos últimos directamente.static const
matriz, para asegurarse de que siempre existió (pero no se proporcionó lenguaje en la pregunta, por lo que traté de no asumir ninguno en la respuesta )El problema con la
if...else if...
cadena es que cuando vengo a leerlo, tengo que mirar cadaif
condición para entender lo que está haciendo el programa. Por ejemplo, podría tener algo como esto:(obviamente, para un pequeño número de declaraciones como esta, no es tan malo)
No tendría forma de saber que cambiaste la variable de condición a la mitad sin leer cada declaración. Sin embargo, debido a que lo
switch
limita a una sola variable de condición, puedo ver de un vistazo lo que está sucediendo.Al final del día, sin embargo, preferiría ninguno
switch
o una cadena deif...else if
. A menudo, una mejor solución es algún tipo de tabla de salto o diccionario para casos como en la pregunta original, o polimorfismo (si su idioma lo admite). No siempre es posible, por supuesto, pero buscaría una solución que eviteswitch
como primer paso ...fuente
La forma anterior de escribir este tipo de mayúsculas y minúsculas es bastante común. La razón por la que sintió la caja del interruptor si es más voluminosa es porque su cuerpo era solo una línea y con una caja del interruptor también necesitaba la declaración de interrupción. Por lo tanto, la caja del interruptor tenía el doble del tamaño del cuerpo de lo contrario. Con un código más sustancial, la declaración de ruptura no agregará mucho al cuerpo. Para el cuerpo de una sola línea, es una práctica común escribir el código en la misma línea que la declaración del caso.
Como otros ya han mencionado, un caso de cambio aclara la intención, desea tomar una decisión basada en el valor de una sola variable / expresión. Mis comentarios son puramente desde un punto de vista de legibilidad y no se basan en el rendimiento.
fuente
return
la cadena adecuada, puede eliminar lasbreak
declaraciones.En este caso, la declaración de cambio coincide más claramente con la intención del código: elija una acción para realizar en función de un solo valor.
Las declaraciones if, por otro lado, son mucho más difíciles de leer: debe verlas todas para asegurarse de lo que está sucediendo. Para mí es menos código (incluso si el recuento de caracteres puede ser un poco más alto) ya que hay menos para analizar mentalmente.
fuente
Estoy de acuerdo con Jerry en que una serie de cadenas es mejor para este caso en particular, pero que en general es mejor usar una declaración de cambio / caso que una cadena de otras cosas. Es más fácil de leer y, a veces, el compilador puede hacer un mejor trabajo de optimización de esa manera, pero también hay otro beneficio: es muchísimo más fácil de depurar.
Cuando presiona ese interruptor, solo tiene que dar un paso una vez para terminar en la rama correcta, en lugar de pasar con cuidado por varias declaraciones if una a la vez, y posiblemente presionar la tecla demasiado rápido y pasar por alto y perder algo y tener comenzar de nuevo.
fuente
Prefiero cambiar en ese tipo de casos, coincide mucho mejor con el punto del código, ejecutar una declaración diferente para cada valor de entrada diferente. El
if..else
actúa más como un "truco" para lograr el mismo efecto.switch
las declaraciones también son más limpias, es fácil tener un error tipográfico oculto en todos esos==
Además, para bloques grandes en C, el cambio es más rápido.
else..if
puede ser más apropiado cuando tienes algo como rangos (entre 1 y 100, haz esto, entre 100 y 200 haz eso), o en C, cuando intentas hacer un cambio con elementos como cadenas (eso es posible en otros idiomas). Que es lo mismo.Tiendo a usar muchos interruptores cuando programo en C.
fuente
Elija algo que sea eficiente, conciso, y luego documente no solo lo que ha hecho, sino también por qué.
El código puede ser revisado, y no siempre por su autor original.
Hay momentos en los que puede elegir deliberadamente una implementación sobre otra porque está pensando en el código que no existe.
fuente
Generalmente no me gusta ninguno de los enfoques. Cambio largo o si las declaraciones solo piden ser refactorizadas a una abstracción orientada a objetos (sin embargo, su ejemplo lo clasificaría como corto, no largo).
Personalmente, envolvería ese tipo de código en un método auxiliar separado.
Colocar el interruptor en un método separado le permite colocar declaraciones de retorno directamente dentro de la declaración del interruptor (al menos en c #), eliminando la necesidad de declaraciones de interrupción, lo que hace que el código sea mucho más fácil de leer.
Y esto es mucho mejor que el enfoque if / else if / else if.
fuente
En python, no hay una declaración de cambio, porque si / elif / else es bueno:
Simple derecho?
fuente
Elif
es solo una declaración if con algunas letras faltantes. Definitivamente es más como unaif
declaración que una declaración de cambio. El hecho de que Python NO tenga un interruptor hace que alguien que los odia (como yo) piense que no están solos.meta
menos que sea un tema conocido. Gracias por darme un testigo.Una de las cosas que hace que el estilo C / C # sea
switch
particularmente molesto es la insistencia en que elcase
valor sea literal. Una cosa buena de VB / VB.NET es queselect/case
permite que cada caso sea una expresión booleana. Eso es conveniente En la medida en que una serie de expresiones booleanas mutuamente excluyentes a menudo es útil, una serie de if / else ifs es más flexible, sin mencionar que es más eficiente para escribir y leer.fuente