В конце шестидесятых Эдсгер Дейкстра написал статью об использовании оператора goto, подчеркнув, как он способствует распространению стиля неструктурированного кода, который часто трудно понять: так называемый код спагетти. Предлагаемой мерой было удаление оператора goto из всех языков программирования высокого уровня в пользу использования структурных конструкций потока управления, таких как if / else, while , повтор и т. д.

В настоящее время почти никто больше не использует оператор goto при написании программ на языках высокого уровня, хотя этот оператор все еще поддерживается такими языками, как C / C ++, C #, PHP.

Это можно было считать хорошим результатом. К сожалению, проблема спагетти-кода не зависит от конкретного утверждения, а в основном от мышления разработчика. Хотя хорошо известно, что идея использования оператора goto является «неподобающим», тенденция к написанию кода прыгающего не исчезла.

Хорошо, goto - это зло, но поскольку во многих языках программирования есть такие операторы, как break, continue, exit, return, какой вред от их использования? И поэтому оператор goto снова вступает в игру, замаскированный под законный оператор, замаскированный goto, как в следующем коде JavaScript:

Что не так с этим блоком кода? Ничего такого. С функциональной точки зрения это правильно. Он делает именно то, что должен: он обрезает строку до указанного количества символов (10 символов, если не указано иное) и добавляет в конец многоточие.

Однако этот код не сводит меня с ума от его читабельности. У меня создается впечатление программирования попытками, без организованных и последовательных рассуждений. Похоже, он следует какой-то стратегии вроде теперь, когда я получил приемлемый результат, позволь мне уйти, прежде чем я попаду в поток, который я не могу контролировать. »
Это пример кода, едва написанного для машины, не для человека.

В этом конкретном случае я предпочитаю подход, при котором функция или блок кода имеют единую точку входа и должны иметь единственную точку выхода. Читатели кода должны иметь возможность линейно понимать, что возвращается, без необходимости искать в операторах, составляющих тело функции.

Использование маскированных переходов является признаком того, что демонизации и удаления конструкции или оператора из языка часто недостаточно для предотвращения неправильного использования. Образ мышления разработчика может раскапывать по-разному. На мой взгляд, код, в котором используются маскированные переходы, демонстрирует нерешительность разработчика в отношении предлагаемого решения. Это немного похоже на лепет, безукоризненное бормотание, без веского аргумента, и его нелегко прочесть.

Использование маскированных переходов должно быть очень редким исключением, и инструменты разработки должны по-разному препятствовать их использованию. К сожалению, некоторые из наиболее часто используемых языков программирования могут предполагать, что на самом деле использование маскированного перехода не причинит вреда. Например, оператор switch в таких языках, как C / C ++, C #, Java, JavaScript и т. Д., Включает использование break, чтобы избежать провала , т.е. переход к операторам, связанным со следующим блоком case:

Я всегда задавался вопросом, почему мы до сих пор сохраняем наследие языка C? Почему при определении современных языков, таких как Java и C #, они не выбрали подход семейства Паскаля, в котором выполняется только выбранный блок case? Кажется, это более последовательный стиль для структурированного языка. Наличие оператора break внутри конструкции switch может подсознательно оправдать некоторых разработчиков в использовании замаскированных переходов как совершенно законных.

В заключение я все еще считаю обоснованной аргументацию Дейкстры относительно использования инструкции goto (замаскированной или нет), но я думаю, что проблема не в самом заявлении, а в том, как разработчик выражает свои доводы. Слишком часто это диалог с машиной, а не с человеком-читателем.

Кстати, это более читаемая (на мой взгляд) версия кода из предыдущего примера: