2010-07-10 14 views
18

Hace algunos días comencé un proyecto de código abierto rápido y, cuando algunos compañeros miraban el código en svn, uno de ellos me dijo que usar la instrucción break dentro de un for se considera perjudicial y no debería hacerse.¿Romper un bucle "for" usando "break" considerado dañino?

añadió, sin embargo, que iba a encontrar varios casos de sentencias dentro breakfor bucles en el código fuente del kernel de Linux, pero eso fue sólo porque sólo Linus Torvalds y Chuck Norris se les permitió usarlo y nadie más.

¿Qué opinas? No veo ningún problema en usar break dentro de un bucle for. En mi opinión, emular el comportamiento de break usando variables booleanas o algo similar agrega mucha sobrecarga innecesaria y hace que el código sea menos directo.

Además, no hay espacio para la comparación con goto, porque break no se puede cambiar arbitrariamente el flujo del programa a partir de un punto a otro mentira goto hace.

+2

Pregunta duplicada: http://stackoverflow.com/questions/216359/break-statements-in-the-real-world Y otra, cerrada como duplicado: http://stackoverflow.com/questions/616339/ is-break-evil –

+0

Creo que 'continue' se considera" dañino ", en la misma liga que" goto "(ambos pueden ser útiles, pero ambos pueden oscurecer el código). 'break' me parece bien, personalmente. –

+2

Utilizo 'break' muy seguido, y' continue' bastante seguido también. Creo que - y lo mismo se aplica a las declaraciones de múltiples, Delphi 'while', etc., etc. - que en la mayoría de los casos cuando alguien dice" no usen el constructo X ", entonces él/ella está no muy acostumbrado a escribir algoritmos complejos y/o que no tiene mucha experiencia en el idioma en cuestión. Porque, si uno tiene mucha experiencia en el lenguaje en cuestión, entonces uno sabe cómo usar este constructo, y si uno a menudo escribe algoritmos complejos, entonces uno amará todos estos constructos. –

Respuesta

42

No veo ningún problema con el uso de los descansos. Siempre habrá circunstancias en las que desee detener el procesamiento de un bucle, y usar un break; tiene mucho más sentido (y lo hace más legible) que configurar el contador de bucle hasta un valor que haría que su bucle se detenga en la siguiente iteración.

+7

No veo ningún problema con el uso de goto. Siempre habrá circunstancias en las que desee detener el procesamiento de un bucle muy anidado y el uso de goto; tiene más sentido (¡y lo hace más legible!) que tener valores booleanos que le digan cuándo salir de los bucles. –

39

obligatorio:

XKCD Goto

El punto es que no se debe evitar que puramente por razones de mala práctica (o velocirráptores), pero tenga en cuenta sobre una base de caso por caso.

Todo se trata de claridad. Como dijiste, nunca debes usarlo, pero en algunos casos promueve la legibilidad. Es útil cuando el ciclo generalmente termina normalmente, pero en casos excepcionales tiene que rescatar. Los bucles que habitualmente (o siempre) se rompen son más un olor a código (pero aún podrían ser apropiados).

+11

+1 por dar una buena respuesta con este cómic. Recuerdo haber visto una respuesta muy subidas de tono que era este comic y nada más, ugh. – Maulrus

1

Creo que depende del contexto. Si bien puede ser un "mal" estilo de codificación en algunas situaciones, no puedo pensar en un caso en el que sería dañino.

De hecho, en algunos casos lo recomendaría. Por ejemplo, si estuviera utilizando una búsqueda lineal, en cualquier caso (excepto en el caso más desfavorable), un break mejoraría su velocidad. Creo que salir del circuito cuando haya encontrado su aguja sería perfectamente aceptable, y sería más legible que jugar con la variable de ciclo (que podría no ser utilizada únicamente para el ciclo, dependiendo de su programa) o envolviendo el cuerpo del lazo en un bloque if. (Y la otra opción, una if que contiene continue, combina lo peor de dos mundos:. Lógica de bucle de envoltura en un bloque de if, y el estilo de codificación poco lanzado en contra de personas como sus amigos que no les gusta break)

+0

No debe recomendar la interrupción por motivos de rendimiento. Los compiladores generalmente pueden optimizar las variables de estado. – Artelius

+0

Punto justo. El punto que estaba tratando de hacer era, por ejemplo, si realizo una búsqueda lineal en una gran cantidad de elementos y encuentro lo que estoy buscando en el índice 2, preferiría dejar de buscar y seguir repitiendo. los elementos restantes que sé que no quiero. Por otro lado, si sé que tendré una gran cantidad de elementos, probablemente no iría a la búsqueda lineal, de todos modos. –

20

No solo no hay problema para usar break, yo diría que cualquiera que diga que es "considerado dañino" es francamente incorrecto.

break es una característica de idioma utilizada para cancelar un ciclo: puede usar goto, pero luego incurre en la ira (apropiada) del comic de XKCD a continuación. Podría usar una bandera en la condición, pero eso dificulta la legibilidad. break no solo es la forma más fácil, sino también la más clara, de salir de un bucle muchas veces.Úselo como debería ser usado.


Editar: para llegar a una imagen más grande aquí: Cuando se está escribiendo código, el principio rector de "¿Debo usar característica del lenguaje X o Y" deben ser "de qué manera dará lugar a la mayor código elegante "? Elegancia, en código, es más o menos un arte, pero lo definiría como un equilibrio entre la legibilidad y la eficiencia algorítmica (léase: no micro optimizaciones). La legibilidad se determinará por la longitud, la complejidad del código, etc. Un boost :: one de una línea puede ser más difícil de leer que un ciclo de 3 líneas.

Si una función de idioma puede ayudarlo a escribir un código que sea más fácil de entender mientras realiza el trabajo, entonces úselo. Esto se aplica a break, goto, excepciones de C++, etc. No siga una "X es (malo | considerada nociva)" ciegamente: aplique el sentido común y la lógica cada vez.

2

Existe un paradigma de que cualquier bucle solo debe tener un punto de salida (lo mismo que una función solo debería tener un retorno). Esto tiene que ver con la legibilidad. Demasiados puntos de salida pueden hacer que el código sea muy difícil de entender. Además, es importante si desea hacer la verificación del código (es decir, prueba matemática si su código es correcto).

Sin embargo, las pautas a menudo ayudan, pero no son estrictas. Posiblemente hay situaciones en las que un descanso es mejor que no usarlo. Por lo tanto, uno debe ser pragmático al respecto, pero comprender la razón de tales principios para crear un buen código.

1

Incrementar el contador de bucles en lugar de utilizar el salto también significa que termina de ejecutar la iteración actual del bucle, que puede o no ser deseable.
Por supuesto, usted podría envolver el resto de ella en una cláusula if, y luego hacerlo de nuevo cuando se da cuenta que necesita para comprobar si es o no dejar de bucle varias veces, y se dará cuenta rápidamente por qué la gente usa break;

11

No solo no hay problema con break, sino que también es OK to use goto cuando break es insuficiente. Tampoco le tengas miedo a los retornos múltiples.

Todo lo anterior solo se aplica si hace que el código sea más fácil de entender *.

* Y si su PHB lo permite ...

1

sugiero este algoritmo si está considerando el uso de una técnica determinada.

  • Si se considera buena práctica :
    • lo utilizan.
  • Si es no considera una buena práctica:
    • lo usan sólo si se juzga que sea la mejor solución a largo plazo.
  • Si se considera el mal :
    • lo usan sólo si se juzga que sea la mejor solución a largo plazo y que esté muy seguro de su juicio. Cuidado: las cosas que se consideran malvadas tienden a ser engañosamente atractivas.

yo clasificaría break; como "no buena práctica". Úselo cuando haga que el código sea más legible, reduzca la posibilidad de errores, no complique la depuración, etc.

+0

Uso break todo el tiempo ... –

7

Creo que su compañero está loco. break es perfectamente aceptable, perfectamente legible y perfectamente mantenible. Período.