Конструкции потока управления более высокого уровня, как правило, соответствуют понятиям в проблемной области. If / else - это решение, основанное на некотором условии. Цикл говорит, что нужно выполнить какое-то действие повторно. Даже в заявлении о перерыве говорится, что «мы делали это неоднократно, но теперь нам нужно остановиться».
Оператор goto, с другой стороны, имеет тенденцию соответствовать концепции в запущенной программе, а не в проблемной области. Он говорит, чтобы продолжить выполнение в указанной точке программы . Кто-то, читающий код, должен сделать вывод, что это означает в отношении проблемной области.
Конечно, все конструкции более высокого уровня могут быть определены в терминах gotos и простых условных ветвей. Это не значит, что они просто замаскированы. Думайте о них как об ограниченных действиях - и именно ограничения делают их полезными. Оператор break реализован как переход к концу окружающего цикла, но его лучше рассматривать как работу с циклом в целом.
При прочих равных условиях код, структура которого отражает структуру проблемной области, легче читать и поддерживать.
Не существует случаев, когда оператор goto абсолютно необходим ( на этот счет есть теорема ), но есть случаи, когда это может быть наименее плохим решением. Эти случаи варьируются от языка к языку, в зависимости от того, какие конструкции более высокого уровня поддерживает язык.
Например, в Си я считаю, что есть три основных сценария, в которых уместно использовать goto.
- Выход из вложенной петли. В этом не было бы необходимости, если бы в языке был помеченный оператор break.
- Выход из участка кода (обычно тела функции) в случае ошибки или другого непредвиденного события. Это было бы ненужным, если бы в языке были исключения.
- Реализация явного конечного автомата. В этом случае (и, я думаю, только в этом случае) goto соответствует непосредственно концепции в проблемной области, переходя из одного состояния в указанное другое состояние, где текущее состояние представлено тем, какой блок кода в настоящее время выполняется ,
С другой стороны, явный конечный автомат также может быть реализован с помощью оператора switch внутри цикла. Это имеет то преимущество, что каждое состояние начинается в одном и том же месте в коде, что может быть полезно, например, для отладки.
Основное использование goto на достаточно современном языке (который поддерживает if / else и циклы) - это имитация конструкции потока управления, которая отсутствует в языке.