Шаг 69.
Язык программирования Go.
Функции panic() и recover()

    На этом шаге рассмотрим обработку исключений в Go.

    В языке Go имеется механизм обработки исключений, реализованный в виде встроенных функций panic() и recover(). Характерный для языка Go способ обработки ошибок заключается в том, чтобы возвращать из функции или метода значение ошибки в последнем (или единственном) возвращаемом значении и всегда проверять все возвращаемые ошибки.

    В случае "невозможной" ситуации можно вызвать встроенную функцию panic() с любым значением (например, строкой, описывающей проблему).

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

    Когда вызывается встроенная функция panic(), немедленно прекращается выполнение вызывающей функции или метода. Затем вызываются все отложенные функции или методы, как в случае нормального завершения функции. И наконец, управление передается вызывающей функции или методу, как если бы эта функция или метод вызвала функцию panic(), – теперь тот же процесс повторяется в вызывающей функции: ее выполнение прекращается, вызываются отложенные функции и т. д. Когда будет достигнута функция main(), ей некому возвращать управление, поэтому в этой точке программа завершается с выводом трассировочной информации в поток os.Stderr, включающей значение, переданное при вызове функции panic().

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

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

    Другое решение заключается в выполнении операций по освобождению ресурсов и повторному вызову функции panic(), чтобы передать аварийную ситуацию дальше. Более универсальное решение предполагает создание значения ошибки и передачу его в виде последнего (или единственного) возвращаемого значения функции с отложенным вызовом recover(), то есть преобразование исключения (аварийной ситуации) в ошибку (в значение типа error).

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

    На следующем шаге рассмотрим пример обработки исключений в Go.


Предыдущий шаг Содержание Следующий шаг