Siempre he oído hablar de una función de punto de salida único como una mala forma de codificar porque pierde legibilidad y eficiencia. Nunca escuché a nadie discutir del otro lado.
Pensé que esto tenía algo que ver con CS, pero esta pregunta fue rechazada en cstheory stackexchange.
coding-style
hexadecimal bob-omb
fuente
fuente
Respuestas:
Hay diferentes escuelas de pensamiento, y en gran parte se reduce a preferencias personales.
Una es que es menos confuso si hay un solo punto de salida: tiene un solo camino a través del método y sabe dónde buscar la salida. En el lado negativo, si usa sangría para representar el anidamiento, su código termina con una sangría masiva a la derecha y se vuelve muy difícil seguir todos los ámbitos anidados.
Otra es que puede verificar las condiciones previas y salir temprano al comienzo de un método, de modo que sepa en el cuerpo del método que ciertas condiciones son verdaderas, sin que todo el cuerpo del método tenga sangría a 5 millas hacia la derecha. Esto generalmente minimiza la cantidad de ámbitos de los que tiene que preocuparse, lo que hace que el código sea mucho más fácil de seguir.
Una tercera es que puede salir por cualquier lugar que desee. Esto solía ser más confuso en los viejos tiempos, pero ahora que tenemos editores y compiladores de colores de sintaxis que detectan código inalcanzable, es mucho más fácil de manejar.
Estoy de lleno en el campo del medio. Hacer cumplir un solo punto de salida es una restricción inútil o incluso contraproducente en mi humilde opinión, mientras que salir al azar en todo un método a veces puede conducir a una lógica complicada y difícil de seguir, donde se vuelve difícil ver si un fragmento de código dado será o no. ejecutado. Pero "activar" su método permite simplificar significativamente el cuerpo del método.
fuente
singe exit
paradigma a fuerza dego to
declaraciones. Además, uno tiene la oportunidad de realizar algún posprocesamiento bajo laError
etiqueta local de la función , lo cual es imposible con múltiplesreturn
s.Mi recomendación general es que las declaraciones de retorno deben, cuando sea práctico, ubicarse antes del primer código que tiene efectos secundarios o después del último código que tiene efectos secundarios. Consideraría algo como:
más claro que:
Si una determinada condición debería evitar que una función haga algo, prefiero regresar antes de la función en un punto por encima del punto donde la función haría cualquier cosa. Sin embargo, una vez que la función ha emprendido acciones con efectos secundarios, prefiero regresar desde abajo, para dejar en claro que se deben tratar todos los efectos secundarios.
fuente
ok
variable, me parece un enfoque de retorno único. Además, el bloque if-else se puede reescribir simplemente a:return ok ? 0 : ERR_NOT_OK;
return
al principio antes de todo el código que hace todo. En cuanto al uso del?:
operador, escribirlo en líneas separadas facilita en muchos IDE adjuntar un punto de interrupción de depuración al escenario no correcto. Por cierto, la clave real del "punto de salida único" radica en comprender que lo que importa es que para cada llamada en particular a una función normal, el punto de salida es el punto inmediatamente después de la llamada . Los programadores hoy en día dan eso por sentado, pero las cosas no siempre fueron así. En algunos casos raros, el código puede tener que funcionar sin espacio de pila, lo que lleva a funciones ...El punto de entrada y salida único era el concepto original de programación estructurada frente a la codificación de espagueti paso a paso. Existe la creencia de que varias funciones de punto de salida requieren más código, ya que debe realizar una limpieza adecuada de los espacios de memoria asignados para las variables. Considere un escenario en el que la función asigna variables (recursos) y salirse de la función antes de tiempo y sin una limpieza adecuada resultaría en pérdidas de recursos. Además, construir una limpieza antes de cada salida crearía una gran cantidad de código redundante.
fuente
Con casi cualquier cosa, se reduce a las necesidades del entregable. En "los viejos tiempos", el código espagueti con múltiples puntos de retorno invitaba a pérdidas de memoria, ya que los programadores que preferían ese método normalmente no se limpiaban bien. También hubo problemas con algunos compiladores que "perdieron" la referencia a la variable de retorno cuando la pila se extrajo durante el retorno, en el caso de regresar de un ámbito anidado. El problema más general fue el código reentrante, que intenta que el estado de llamada de una función sea exactamente el mismo que su estado de retorno. Los mutadores de oop violaron esto y el concepto fue archivado.
Hay entregables, sobre todo kernels, que necesitan la velocidad que proporcionan múltiples puntos de salida. Estos entornos normalmente tienen su propia memoria y gestión de procesos, por lo que se minimiza el riesgo de una fuga.
Personalmente, me gusta tener un solo punto de salida, ya que a menudo lo uso para insertar un punto de interrupción en la declaración de retorno y realizar una inspección de código de cómo el código determinó esa solución. Podría simplemente ir a la entrada y pasar, lo que hago con soluciones recursivas y anidadas extensivamente. Como revisor de código, múltiples retornos en una función requieren un análisis mucho más profundo, por lo que si lo está haciendo para acelerar la implementación, le está robando a Peter para salvar a Paul. Se requerirá más tiempo en la revisión del código, invalidando la presunción de implementación eficiente.
- 2 centavos
Consulte este documento para obtener más detalles: NISTIR 5459
fuente
multiple returns in a function requires a much deeper analysis
solo si la función ya es enorme (> 1 pantalla); de lo contrario, facilita el análisisEn mi opinión, el consejo de salir de una función (u otra estructura de control) en un solo punto a menudo está sobrevendido. Por lo general, se dan dos razones para salir en un solo punto:
La segunda razón es sutil y tiene algún mérito, especialmente si la función devuelve una gran estructura de datos. Sin embargo, no me preocuparía demasiado por eso, excepto ...
Si es estudiante, desea obtener las mejores calificaciones en su clase. Haz lo que prefiera el instructor. Probablemente tenga una buena razón desde su perspectiva; así, como mínimo, aprenderás su perspectiva. Esto tiene valor en sí mismo.
Buena suerte.
fuente
Solía ser un defensor del estilo de salida única. Mi razonamiento provino principalmente del dolor ...
La salida única es más fácil de depurar.
Dadas las técnicas y herramientas que tenemos hoy, esta es una posición mucho menos razonable para tomar, ya que las pruebas unitarias y el registro pueden hacer que la salida única sea innecesaria. Dicho esto, cuando necesita ver la ejecución de código en un depurador, es mucho más difícil de entender y trabajar con código que contiene múltiples puntos de salida.
Esto se volvió especialmente cierto cuando necesitaba interponer asignaciones para examinar el estado (reemplazado por expresiones de observación en los depuradores modernos). También fue demasiado fácil alterar el flujo de control de manera que ocultara el problema o rompiera la ejecución por completo.
Los métodos de salida única eran más fáciles de recorrer en el depurador y más fáciles de separar sin romper la lógica.
fuente
La respuesta depende mucho del contexto. Si está creando una GUI y tiene una función que inicializa las API y abre ventanas al comienzo de su principal, estará llena de llamadas que pueden arrojar errores, cada uno de los cuales provocaría el cierre de la instancia del programa. Si usó declaraciones IF anidadas y sangría, su código podría volverse rápidamente muy sesgado hacia la derecha. Devolver un error en cada etapa puede ser mejor y, en realidad, más legible, al mismo tiempo que es igual de fácil de depurar con algunos indicadores en el código.
Sin embargo, si está probando diferentes condiciones y devolviendo diferentes valores según los resultados en su método, puede ser una práctica mucho mejor tener un solo punto de salida. Solía trabajar en scripts de procesamiento de imágenes en MATLAB, que podían volverse muy grandes. Múltiples puntos de salida pueden hacer que el código sea extremadamente difícil de seguir. Las declaraciones de cambio eran mucho más apropiadas.
Lo mejor que puede hacer es aprender sobre la marcha. Si está escribiendo código para algo, intente buscar el código de otras personas y ver cómo lo implementan. Decide qué bits te gustan y cuáles no.
fuente
Si siente que necesita varios puntos de salida en una función, la función es demasiado grande y está haciendo demasiado.
Recomendaría leer el capítulo sobre funciones en el libro de Robert C. Martin, Código limpio.
Esencialmente, debería intentar escribir funciones con 4 líneas de código o menos.
Algunas notas del blog de Mike Long :
fuente