Я только что прочитал этот пост о Panic / Recover in Go, и мне не ясно, чем это отличается от try / catch в других основных языках.
Я продолжаю смотреть на этот вопрос, пытаясь придумать лучший способ на него ответить. Проще всего указать на идиоматические варианты использования panic / recovery в отличие от try / catch & | исключения в других языках или концепции, лежащие в основе этих идиом (которые можно в основном резюмировать как «исключения должны происходить только в действительно исключительных обстоятельствах»)
. Но какова действительная разница между ними? Я постараюсь резюмировать как можно лучше.
Одним из основных отличий от блоков try / catch является способ управления потоками. В типичном сценарии try / catch код после блока catch будет выполняться, если он не распространяет ошибку. Это не так с panic / recovery . Паника прерывает текущую функцию и начинает раскручивать стек, выполняя отложенные функции (единственное место, где восстановление делает что-либо), когда она встречает их.
На самом деле, я бы пошел еще дальше: panic / recovery почти не похоже на try / catch в том смысле, что try and catch являются (или, по крайней мере, действуют как) контролем структур, а паника / восстановление - нет.
Это действительно связано с тем фактом, что восстановление построено на механизме отсрочки, который (насколько я могу судить) является довольно уникальной концепцией в Go.
Конечно, есть и другие, которые я добавлю, если смогу немного активизировать свои мысли.
defer - это механизм не только для обработки ошибок, но и для удобной и контролируемой очистки. Теперь паника работает как raise () на других языках. С помощью функции recovery () у вас есть шанс поймать эту панику, пока она поднимается по стеку вызовов. Таким образом, это почти похоже на попытку / поймать. Но пока последний работает на блоках, паника / восстановление работает на функциональном уровне.
Роб Пайк о причине такого решения: «Мы не хотим поощрять смешение ошибок и исключений, которые возникают в таких языках, как Java». Вместо того, чтобы иметь большое количество различных исключений с еще большим количеством использований, следует делать все, чтобы избежать ошибок во время выполнения, предоставлять правильные возвращаемые значения ошибок после определения и использовать панику / восстановление только в том случае, если нет другого пути.
Паника/Восстановление относятся к области действия функции. Это все равно, что сказать, что вам разрешен только один блок try/catch в каждой функции, и попытка должна охватывать всю функцию. Это очень раздражает использование Panic/Recover так же, как java/python/c# и т. д. используют исключения. Это сделано намеренно. Это также побуждает людей использовать Panic/Recover так, как это было задумано. Вы должны восстановить () из паники (), а затем вернуть значение ошибки вызывающей стороне.