Есть ли в Go конструкция try-catch для обработки исключений
Что проверяют
Понимаете ли вы философию Go: ошибка это обычное значение, а не исключение, которое летит по стеку. Следом спрашивают про panic и recover: чем они отличаются от исключений и когда уместны.
Как отвечать
Коротко: try-catch в Go нет. Функция возвращает ошибку последним значением, вызывающий проверяет её явно через if err != nil. Дальше покажите, что умеете работать с ошибками современно:
error: обычный интерфейс с методомError() string, свои типы ошибок делаются структурами;- обёртка:
fmt.Errorf("load user %d: %w", id, err)добавляет контекст и сохраняет исходную ошибку; errors.Is: проверка на конкретную sentinel-ошибку по всей цепочке обёрток, напримерsql.ErrNoRowsилиio.EOF;errors.As: достать ошибку конкретного типа, чтобы прочитать её поля;errors.Join: объединить несколько ошибок в одну, появился в Go 1.20.
panic и recover существуют, но это не замена исключениям. Паника для ситуаций, которые не должны случаться: нарушенный инвариант, ошибка программиста, невозможность стартовать. recover работает только внутри отложенной через defer функции и только в той горутине, где случилась паника. Типичное место для него: граница, например middleware HTTP-сервера, которое превращает панику в ответ 500. Сам net/http перехватывает панику обработчика, но паника в горутине, запущенной из обработчика, уронит весь сервер.
Предложения добавить в язык сокращённую проверку, вроде встроенной try, обсуждались не раз и приняты не были.
Где спотыкаются
Сравнивают обёрнутую ошибку через ==. После %w это уже другое значение, сравнение вернёт false, нужен errors.Is.
Надеются, что recover в main поймает панику из другой горутины. Не поймает: паника в горутине без своего recover роняет процесс.
Возвращают типизированный nil. Функция объявлена с результатом error, внутри var e *MyErr = nil; return e, и вызывающий получает err != nil: у интерфейса есть тип, хоть и без значения.