Различие между GOTO и БРОСКОМ?

Многие люди недавно обвинили меня в том, что я просто упомянул отдельное слово - "goto".
Это заставляет меня задаться вопросом, почему это считают таким непристойным словом.
Я знаю о нескольких предыдущих обсуждениях темы, но она не убеждает меня - в некоторых ответах просто говорится, что "она плохо" даже не пытается объяснить, и некоторые приносят причины, не важные для языков сценариев как PHP, IMO.

Так или иначе я собираюсь задать очень конкретный вопрос:
Давайте сравним goto и throw операторы.
Оба, по-моему, делают то же самое: предотвращение выполнения некоторой части кода на основе некоторого условия.
Раз так - делают throw имеют те же недостатки как goto? (если таковые имеются)?
Если не - с различие затем.

Кто-либо испытал достаточно, кто может сказать фундаментальное, концептуальное различие между структурами кода двух после фрагментов кода?
Относительно этих самых фрагментов кода не "в теории" или "в целом" или "вот хороший комик XKCD!".
Почему первый считал блестящим и последним считавшимся самым смертельным из грехов?

#$a=1;
#$b=2;

/* SNIPPET #1 */

try {
    if (!isset($a)) {
      throw new Exception('$a is not set');
    }
    if (!isset($b)) {
      throw new Exception('$b is not set');
    }
    echo '$a + $b = '.($a + $b)."
\n"; } catch (Exception $e) { echo 'Caught exception: ', $e->getMessage(), "
\n"; } /* SNIPPET #2 */ if (!isset($a)) { $message = '$a is not set'; goto end; } if (!isset($b)) { $message = '$b is not set'; goto end; } echo '$a + $b = '.($a + $b)."
\n"; end: if (!empty($message)) { echo 'Caught exception: ', $message, "
\n"; }

Обратите внимание, что я знаю о том, что бросок более мощен и гибок в создании спагетти. Это не имеет основного значения для меня. Это - вопрос использования, не понятие.

Править
Мне сказали многие люди, что первый пример должен быть более новый используемый.
Причина: Исключения должны использоваться, чтобы обработать ошибки только, не реализовать бизнес-логику.
Это выглядит разумным.

Поэтому единственным путем, оставленным остановить бесполезное выполнение кода, является goto (не говоря уже о некоторых заменах, такой как, в то время как, возвратитесь и т.д., которые являются тем же вопросом, но тяжелее реализовать)?

8
задан Community 23 May 2017 в 12:23
поделиться

8 ответов

goto может немного повысить производительность по сравнению с throw, поскольку он не создает стек исключений.

1
ответ дан 5 December 2019 в 04:58
поделиться

Команда Throw / catch намного более гибкая, чем goto: вы можете поймать из функций, которые вызывают код, генерирующий исключение. Кроме того, необходимые деструкторы вызываются автоматически.

13
ответ дан 5 December 2019 в 04:58
поделиться

Я думаю, вам нужно задать вопрос наоборот: зачем использовать goto , когда исключения идеально подходят для данной ситуации? Вот какие исключения составляют для .

Вы также можете спросить: «Зачем использовать while , для и функций, когда я могу так же легко использовать goto

7
ответ дан 5 December 2019 в 04:58
поделиться

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

Когда исключения полезны, вы вызываете методы, которые могут иметь состояние ошибки, но не могут обработать ее самостоятельно, как показано в следующем псевдокоде:

try
{
    $c = add($a, $b);
    echo '$a + $b = '.($c)."<br>\n";
}
catch (Exception $e)
{
    echo 'Caught exception: ', $e->getMessage(), "<br>\n";
}

Метод add выполняет проверку ошибки:

if (!isset($a))
{
    throw new Exception('$a is not set');
}
if (!isset($b))
{
    throw new Exception('$b is not set');
}

затем возвращает результат сложения.

Это означает, что ваш основной поток кода показывает ожидаемый путь через программу.

5
ответ дан 5 December 2019 в 04:58
поделиться

goto жестко кодирует путь выполнения в коде. С другой стороны, исключения позволяют определить путь выполнения во время выполнения.

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

Помните, что ваш код должен быть многоразовым и гибким. goto - это противоположность тому и другому...

4
ответ дан 5 December 2019 в 04:58
поделиться

На практике разница между двумя сегментами кода состоит в том, что вам придется тратить больше времени, объясняя себя другим программистам с помощью кода «goto».

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

Если вы работаете один и никто не увидит ваш код - используйте все, что вам нравится. Но если вы работаете в команде, иногда разумнее всего идти по пути наименьшего сопротивления.

2
ответ дан 5 December 2019 в 04:58
поделиться

Не используйте ни то, ни другое. Используйте «while (1)» вокруг основной части кода и операторов «break» там, где вы хотите перейти к концу.

while(1)
{
    if (!isset($a)) { 
      $message = '$a is not set';
      break;
    }
    if (!isset($b)) {
      $message = '$b is not set';
      break;
    }

    echo '$a + $b = '.($a + $b)."<br>\n";
    break;
}

if (!empty($message)) {
  echo 'Caught exception: ', $message, "<br>\n";
}
-3
ответ дан 5 December 2019 в 04:58
поделиться

Я не ненавижу GOTO так сильно, как многие, но я думаю, что его главная проблема в том, что он не ограничен определенной «областью действия». С любой другой структурой управления вы знаете, где она начинается и где заканчивается. С другой стороны, метка GOTO может быть размещена в гораздо более непредсказуемых местах. Вы, конечно, можете искать по этикетке, но это мешает читаемости.

Конечно, все зависит от того, как его использовать.

0
ответ дан 5 December 2019 в 04:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: