¿Por qué el compilador no coloca automáticamente declaraciones break después de cada bloque de código en el conmutador? ¿Es por razones históricas? ¿Cuándo desea que se ejecuten varios bloques de código?
94
¿Por qué el compilador no coloca automáticamente declaraciones break después de cada bloque de código en el conmutador? ¿Es por razones históricas? ¿Cuándo desea que se ejecuten varios bloques de código?
break
.Respuestas:
A veces es útil tener varios casos asociados con el mismo bloque de código, como
etc. Solo un ejemplo.
En mi experiencia, por lo general es de mal estilo "fallar" y ejecutar varios bloques de código para un caso, pero puede ser útil en algunas situaciones.
fuente
// Intentional fallthrough.
cuando omita un descanso. En mi opinión, no es tanto un mal estilo como "fácil olvidar una ruptura accidentalmente". PD: Por supuesto que no en casos simples como en la propia respuesta.case
se apilan juntos de esa manera. Si hay un código entre ellos, entonces sí, probablemente el comentario sea merecido.case
, así:,case 'A','B','C': doSomething(); case 'D','E': doSomethingElse();
sin necesidad de un descanso entre los casos. Pascal podría hacer eso: "La declaración del caso compara el valor de la expresión ordinal con cada selector, que puede ser una constante, un subrango o una lista de ellos separados por comas". ( wiki.freepascal.org/Case )Históricamente , se debe a que
case
esencialmente definía unlabel
, también conocido como el punto de destino de unagoto
llamada. La declaración de cambio y sus casos asociados realmente representan una rama de múltiples vías con múltiples puntos de entrada potenciales en un flujo de código.Dicho todo esto, se ha observado un número casi infinito de veces que
break
casi siempre es el comportamiento predeterminado que preferiría tener al final de cada caso.fuente
Java proviene de C y esa es la sintaxis de C.
Hay ocasiones en las que desea que varias declaraciones de casos solo tengan una ruta de ejecución. A continuación se muestra una muestra que le dirá cuántos días en un mes.
fuente
Creo que es un error. Como construcción de lenguaje, es tan fácil de tener
break
como predeterminado y, en su lugar, tener unafallthrough
palabra clave. La mayor parte del código que he escrito y leído tiene un descanso después de cada caso.fuente
continue <case name>
que permite especificar explícitamente con qué declaración de caso continuar;case
dentro de la corrienteswitch
, esto simplemente se convierte en ungoto
. ;-)Puede hacer todo tipo de cosas interesantes con la caída de casos.
Por ejemplo, digamos que desea realizar una acción en particular para todos los casos, pero en un caso determinado desea realizar esa acción y algo más. Usar una declaración de cambio con fallos lo haría bastante fácil.
Por supuesto, es fácil olvidar la
break
declaración al final de un caso y provocar un comportamiento inesperado. Los buenos compiladores le advertirán cuando omita la declaración break.fuente
Dejando a un lado las buenas ganas de poder utilizar el mismo bloque para varios casos (que podrían ser de carcasa especial) ...
Es principalmente por compatibilidad con C, y podría decirse que es un antiguo truco de los días de antaño cuando las
goto
palabras clave vagaban por la tierra. Se hace servir para que algunas cosas increíbles, por supuesto, como el dispositivo de Duff , pero si eso es un punto a su favor o en contra ... es argumentativo en el mejor.fuente
El
break
after switchcase
s se usa para evitar errores en las declaraciones de switch. Aunque es interesante, esto ahora se puede lograr a través de las etiquetas de interruptor recién formadas implementadas a través de JEP-325 .Con estos cambios, el
break
con cada interruptorcase
se puede evitar como se demuestra más adelante: -En ejecutar el código anterior con JDK-12 , la salida comparativa podría verse como
y
y por supuesto la cosa sin cambios
fuente
Por lo tanto, no tiene que repetir el código si necesita varios casos para hacer lo mismo:
O puedes hacer cosas como:
En forma de cascada.
Realmente propenso a errores / confusión, si me preguntas.
fuente
do this
comodo that
para eso, pero solodo that
para eso?En lo que respecta al registro histórico, Tony Hoare inventó el enunciado del caso en la década de 1960, durante la revolución de la "programación estructurada". La declaración de caso de Tony admitía múltiples etiquetas por caso y salida automática sin
break
declaraciones apestosas . El requisito de un explícitobreak
fue algo que salió de la línea BCPL / B / C. Dennis Ritchie escribe (en ACM HOPL-II):No he podido encontrar ningún escrito histórico sobre BCPL, pero el comentario de Ritchie sugiere que
break
fue más o menos un accidente histórico. BCPL luego solucionó el problema, pero quizás Ritchie y Thompson estaban demasiado ocupados inventando Unix para molestarse con tal detalle :-)fuente
break
permite "ejecutar múltiples bloques de código", y está más preocupado por la motivación de esta elección de diseño. Otros mencionaron la herencia bien conocida de C a Java, y esta respuesta llevó la investigación aún más a los días anteriores a C. Ojalá tuviéramos esta coincidencia de patrones (aunque muy primitiva) desde el principio.Java se deriva de C, cuya herencia incluye una técnica conocida como Dispositivo de Duff . Es una optimización que se basa en el hecho de que el control pasa de un caso a otro, en ausencia de una
break;
declaración. Para cuando C se estandarizó, había mucho código como ese "en la naturaleza", y hubiera sido contraproducente cambiar el lenguaje para romper tales construcciones.fuente
Como la gente dijo antes, es para permitir la caída y no es un error, es una característica. Si le
break
molestan demasiadas declaraciones, puede deshacerse de ellas fácilmente utilizandoreturn
declaraciones en su lugar. En realidad, esta es una buena práctica, porque sus métodos deben ser lo más pequeños posible (en aras de la legibilidad y el mantenimiento), por lo que unaswitch
declaración ya es lo suficientemente grande para un método, por lo tanto, un buen método no debe contener nada más, esto es un ejemplo:La ejecución imprime:
como se esperaba.
fuente
No tener una interrupción automática agregada por el compilador hace posible usar un interruptor / caso para probar condiciones como
1 <= a <= 3
eliminar la declaración de interrupción de 1 y 2.fuente
porque hay situaciones en las que desea fluir a través del primer bloque, por ejemplo, para evitar escribir el mismo código en varios bloques, pero aún así poder dividirlos para el control de mroe. También hay un montón de otras razones.
fuente
Es una vieja pregunta, pero en realidad me encontré usando el caso sin una declaración de interrupción hoy. En realidad, no utilizar break es muy útil cuando necesita combinar diferentes funciones en secuencia.
por ejemplo, usando códigos de respuesta http para autenticar al usuario con el token de tiempo
código de respuesta del servidor 401 - el token está desactualizado -> regenerar el token e iniciar la sesión del usuario.
código de respuesta del servidor 200 - el token está bien -> iniciar la sesión del usuario.
en declaraciones de casos:
Con esto, no es necesario llamar a la función de inicio de sesión de usuario para la respuesta 401 porque cuando se regenera el token, el tiempo de ejecución salta al caso 200.
fuente
Puede separar fácilmente otro tipo de número, mes, recuento.
Esto es mejor entonces si en este caso;
fuente
Ahora estoy trabajando en un proyecto donde lo necesito
break
en mi declaración de cambio, de lo contrario, el código no funcionará. Tenga paciencia conmigo y le daré un buen ejemplo de por qué lo necesitabreak
en su declaración de cambio.Imagine que tiene tres estados, uno que espera a que el usuario ingrese un número, el segundo para calcularlo y el tercero para imprimir la suma.
En ese caso tienes:
Mirando los estados, querrá que el orden de exacción comience en state1 , luego state3 y finalmente state2 . De lo contrario, solo imprimiremos la entrada de los usuarios sin calcular la suma. Solo para aclararlo nuevamente, esperamos que el usuario ingrese un valor, luego calculamos la suma e imprime la suma.
Aquí hay un código de ejemplo:
Si no lo usamos
break
, se ejecutará en este orden, estado1 , estado2 y estado3 . Pero al usarbreak
, evitamos este escenario y podemos ordenar el procedimiento correcto que es comenzar con state1, luego state3 y por último, pero no menos importante, state2.fuente
Exactamente, porque con una ubicación inteligente puedes ejecutar bloques en cascada.
fuente