¿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.casese 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
caseesencialmente definía unlabel, también conocido como el punto de destino de unagotollamada. 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
breakcasi 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
breakcomo predeterminado y, en su lugar, tener unafallthroughpalabra 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;casedentro 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
breakdeclaració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
gotopalabras 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
breakafter switchcases 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
breakcon cada interruptorcasese 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 thiscomodo thatpara eso, pero solodo thatpara 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
breakdeclaraciones apestosas . El requisito de un explícitobreakfue 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
breakfue 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
breakpermite "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
breakmolestan demasiadas declaraciones, puede deshacerse de ellas fácilmente utilizandoreturndeclaraciones 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 unaswitchdeclaració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 <= 3eliminar 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
breaken 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 necesitabreaken 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