Goto vs. Throw
По-моему то, что goto — это плохо, придумали не очень умные люди. Это дело разработчика, какие управляющие конструкции использовать. Если разработчик плохой, то он и без goto сделает код непонятным, а если хороший, то goto ему поможет сделать код лучше там, где это возможно.
Самое интересное, что когда люди поняли, что goto всё-таки нужен, но уже было слишком распространено мнение, что «им пользуются только лохи», они придумали throw. Причём, замаскировали его так, чтобы сразу трудно было догадаться, что это просто goto переименовали:
- Сделали синтаксис try/catch (catch — это описание метки, вместо label, а try — просто для симметрии)
- Придумали красивую легенду про то, что это всё вообще для отлова ошибок, точнее даже «исключительных ситуаций», а вовсе не для того, чтобы вернуть goto народу
- Привязали это всё к классам, объектам, иерархии, наследованию (добавьте умные слова по вкусу) — чтобы уж совсем сбить людей с толку
Если писать код лично для себя, то можно без проблем пользоваться goto, или try/catch вместо goto, и даже try/catch там, где нет ничего исключительного.
А вот если писать код, который теоретически может поддерживать кто-то другой... Тогда надо пользоваться общепринятыми стандартами кодирования. А что стандарты эти создавались для... э.. не самых умных людей — тут ничего не поделаешь, рынку этот подход выгоден.
PS: goto запретили потому, что плохие программисты с его помощью пишут код хуже, чем без него.
Ага.
А можно узнать, как планируется с помощью goto передать управление в чужой класс, исходный код которого недоступен?
Например, при написании плагина к чужому приложению — часто требуется отрапортовать об ошибке и отдать управление приложению?
Throw — это расширенный вариант goto, он может больше. Если вы помните, goto был признан плохим потому, что он ломает естественный порядок выполнения кода, из-за чего код часто становится нечитаемым. Однако goto работает только внутри некоторого логического блока, поэтому существенно испортить удобочитаемость кода он не может. Throw решает это проблему, так как позволяет прыгнуть в неопределённую точку пространства, как можно дальше от места, где мы его написали, чтобы никто никогда не понял, как это всё работает.
Так что, безусловно, с помощью goto нельзя сделать всего того, что можно сделать с помощью throw.
Нет, ну try/catch это совсем другой механизм. Может в PHP уже пофигу, но языках более низкого уровня он требует совсем других накладных расходов, что бывает важно. Если кто-то использует try/catch именно как замену goto, то он, прямо скажем, не очень умный человек.
Какой-то дурак сказал, что goto это зло, а все и давай повторять. На самом деле полно исходников на С и С++, в которых goto используется в КАЖДОЙ функции.
Обычный оператор, каких много. А идиотам на слово не надо верить :)
На самом-то деле, для заменты goto придумали совсем другую конструкцию:
%%
while( true ) { // Label1:
// do something
// ...
if( condition )
continue; // Goto Label1:
else
break;
}
%%
WBR,
XOR
Да, wiki-posting мою конструкцию очень сильно подкосил. :(
Я подправил
а как же finally ?
Whatever...
Выясни, для начало, что такое try/catch, а уж потом говори глупости.
!!Выясни, для начало, что такое try/catch, а уж потом говори глупости!!
Хм, хоть стой хоть падай...
Самое распространенное применение goto в С:
%%{
int *i = NULL;
do_something();
if(error) goto err;
do_something2();
i = new i;
do_something3();
if(another_error) goto err;
do_something4();
err:
if(i)
free(i);
}%%
Это — аналог try-catch-finally.
Да... Народ, а читать/учиться будем?
И вообще, причем тут try-catch? Бред какой-то. :-) (без оскорблений, просто мысль такая)
Ну, а то, что Ваня Солнцев накосячил — это совсем да :-)
Самый большой бред — это твой пункт 3. Почему все так любят говорить, что «доказано, что можно обойтись без goto»?
Ну и что?
Доказано, что можно обойтись без: if, else, while, repeat, for, foreach, try, throw, catch, finally, class, abstract, final, private, public, string... Этот список можно продолжать бесконечно. Из этого никак не следует, что нужно отказаться от всего этого.
Эх. Пошаговая процедура:
1 Можно обойтись без goto в подавляющем количестве случаев без значимого количества накладных расходов. Это то, что говорится в п.3 выше как «доказано».
1 Использование goto ухудшает восприятие кода — значимо увеличивает накладные расходы. Это то, что говорится в п.3 выше как «доказано».
1 Из вышеизложенного следует, что использование оператора goto в подавляющем количестве случаев ведёт к накладным расходам (здесь, расходам, не связанным с решением основной задачи).
1 Случаи-исключения (такие, как «многоуровневый цикл») — не попадают под эту процедуру. Это то, что говорится в п. 2 выше.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать оператора goto.
1 Размышления, подобные этой процедуре, являются накладными расходами.
1 Если вашей задачей является оптимизация расходов, то вам лучше избегать этих размышлений.
1 Для избежания размышлений можно пользоваться «правилом» или «табу» на оператор goto. Их ещё называют «шаблонами использования операторов», «шаблонами кода» и подобной чушью.
Если, конечно, Вам действительно была непонятна логика пп.2,3 выше — надеюсь, что это упрощённое разъяснение Вам поможет.
Удачи!
Да понятно это всё. Я ж не о том говорю. А да ну нафиг.
Если коротко, то ГОСТ придумали очень и очень глупые люди, выходит.
Нет же...
Эх. Придётся писать ещё одну заметку на тему «Чем ГОСТ отличается от табу на goto».