error как значение

Тема дорожной карты · Golang

Значения ошибок в Go — основной механизм языка для сообщения об отказах: любой тип, реализующий интерфейс error — единственный метод Error() string — может возвращаться как ошибка из функции. Соглашение Go о возврате пар (result, error) делает обработку ошибок явной и видимой в каждом месте вызова, в отличие от моделей на основе исключений, принятых в Python или Java. Пакет errors предоставляет errors.New("message") для простых сентинельных ошибок, fmt.Errorf("context: %w", err) для оборачивания ошибок с дополнительным контекстом при сохранении цепочки, а errors.Is и errors.As — для проверки обёрнутых ошибок в цепочке без строкового сравнения. Go 1.13 стандартизировал оборачивание и разворачивание ошибок, что позволило библиотекам вроде github.com/pkg/errors прикреплять трассировку стека, а фреймворкам Gin и Echo — транслировать типы доменных ошибок в HTTP-статусы в middleware. Определение пользовательских типов ошибок через реализацию интерфейса error — например, структура ValidationError с полями Field и Message — позволяет Golang-сервисам переносить структурированные данные об ошибках через gRPC-статусы, JSON API-ответы и структурированные записи журналов Zap, Logrus или slog.

Как это работает

error как значение намеренно мал: ключевые слова (var, const, if, for, switch, defer, go, select, return, type, func, package, import), нет классов (struct + методы + интерфейсы), нет исключений (multi-return + error-значения), нет наследования (композиция через embedding). Видимость по регистру: с заглавной — экспорт, со строчной — package-private. := объявляет + присваивает; = — присваивает. defer выполняется при возврате функции — идеально для cleanup. Компилятор не пропустит неиспользуемые импорты + переменные.

Когда применять

Примите минимализм — Go дерётся с попытками умничать. gofmt (без флагов, канонический стиль); коммитьте только отформатированный код. defer — для cleanup в паре с захватом (defer f.Close() сразу после f, err := os.Open(...)). Короткое объявление (:=) внутри функций; var — для zero-valued объявлений или когда нужен конкретный тип.

Типичные ошибки

Ловушки error как значение: for i := range slice и получение и индекса и копии, когда хотели оба (for i, v := range slice); shadow внешних переменных через := ("почему внешняя переменная не изменилась?"); не обрабатывают ошибку немедленно (_, _ = ... игнорирует); глобальное состояние — Go-программы становятся сложными для понимания при shared mutable state.

Связанные понятия

Полезные ресурсы