Las construcciones de flujo de control de nivel superior tienden a corresponder a conceptos en el dominio del problema. Un if / else es una decisión basada en alguna condición. Un bucle dice que realice alguna acción repetidamente. Incluso una declaración de ruptura dice "estábamos haciendo esto repetidamente, pero ahora tenemos que parar".
Una declaración goto, por otro lado, tiende a corresponder a un concepto en el programa en ejecución, no en el dominio del problema. Dice que continúe la ejecución en un punto específico del programa . Alguien que lee el código tiene que inferir lo que eso significa con respecto al dominio del problema.
Por supuesto, todas las construcciones de nivel superior se pueden definir en términos de gotos y ramas condicionales simples. Eso no quiere decir que sean simplemente disfraces disfrazados. Piense en ellos como objetos restringidos , y son las restricciones las que los hacen útiles. Una declaración de interrupción se implementa como un salto al final del ciclo de cierre, pero es mejor pensar que opera en el ciclo como un todo.
En igualdad de condiciones, el código cuya estructura refleja la del dominio del problema tiende a ser más fácil de leer y mantener.
No hay casos en los que sea absolutamente necesaria una declaración goto (hay un teorema para ese efecto), pero hay casos en los que puede ser la solución menos mala. Esos casos varían de un idioma a otro, dependiendo de las construcciones de nivel superior que admita el lenguaje.
En C, por ejemplo, creo que hay tres escenarios básicos donde un goto es apropiado.
- Salir de un bucle anidado. Esto sería innecesario si el idioma tuviera una declaración de rotura etiquetada.
- Rescate de un tramo de código (generalmente un cuerpo de función) en caso de error u otro evento inesperado. Esto sería innecesario si el idioma tuviera excepciones.
- Implementación de una máquina explícita de estados finitos. En este caso (y, creo, solo en este caso) un goto corresponde directamente a un concepto en el dominio del problema, pasando de un estado a otro estado específico, donde el estado actual está representado por qué bloque de código se está ejecutando actualmente .
Por otro lado, una máquina explícita de estados finitos también se puede implementar con una declaración de cambio dentro de un bucle. Esto tiene la ventaja de que cada estado comienza en el mismo lugar en el código, lo que puede ser útil para la depuración, por ejemplo.
El uso principal de un goto en un lenguaje razonablemente moderno (uno que admite if / else y bucles) es simular una construcción de flujo de control que falta en el lenguaje.