> Для чего используется пакет errors в Go (Go)
Уровень: middle · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Lamoda
Стек: Go
> Пример ответа
Короткий ответ
Пакет errors в Go используется для создания ошибок, их обёртывания и проверки. Основные функции: errors.New - создание простой ошибки, errors.Is - проверка на конкретную ошибку в цепочке, errors.As - приведение к определённому типу, errors.Unwrap - получение предыдущей ошибки. Пакет появился в Go 1.13 и стал стандартным инструментом для работы с ошибками вместо ручных сравнений и кастомных обёрток.
Подробное объяснение
До Go 1.13 работа с ошибками была ограничена: можно было только создавать их через errors.New или fmt.Errorf без %w. Проверка на конкретную ошибку требовала сравнения значений или приведения типов через type assertion. Это приводило к хрупкому коду: если ошибка оборачивалась в другую, исходная терялась.
Пакет errors решает три задачи:
-
Создание ошибок -
errors.Newвозвращает значение, реализующее интерфейсerror. В отличие отfmt.Errorf, оно не содержит форматирования, но этого достаточно для простых случаев. -
Обёртывание ошибок - через
fmt.Errorfс%wсоздаётся цепочка ошибок.errors.Unwrapпозволяет достать предыдущую ошибку из цепочки. Это важно для сохранения контекста: вы можете добавить информацию о том, где произошла ошибка, не теряя исходную причину. -
Проверка ошибок -
errors.Isсравнивает ошибку с целевой, проходя по всей цепочке черезUnwrap.errors.Asищет в цепочке ошибку, приводимую к заданному типу, и записывает её в переменную.
Также пакет содержит errors.Join (Go 1.20) для объединения нескольких ошибок в одну, что полезно при валидации или параллельных операциях.
На практике
На собеседовании важно показать, что вы понимаете разницу между errors.Is и errors.As. Первая работает с значениями (sentinel errors), вторая - с типами. Sentinel errors - это предопределённые переменные, например io.EOF, sql.ErrNoRows. Их проверяют через errors.Is. Если ошибка несёт дополнительные данные (например, код HTTP-статуса), её оформляют как тип, реализующий error, и проверяют через errors.As.
Также стоит упомянуть, что errors.New создаёт ошибку с уникальным адресом: две ошибки с одинаковым текстом не равны по значению, поэтому для sentinel errors нужно использовать errors.Is, а не прямое сравнение.
Пример кода
GOpackage mainimport ("errors""fmt")var ErrNotFound = errors.New("item not found")type HTTPError struct {Status intMsg string}func (e *HTTPError) Error() string {return fmt.Sprintf("HTTP %d: %s", e.Status, e.Msg)}func fetch(id int) error {if id == 0 {return fmt.Errorf("fetch: %w", ErrNotFound)}if id == 500 {return &HTTPError{Status: 500, Msg: "internal error"}}return nil}func main() {err := fetch(0)if errors.Is(err, ErrNotFound) {fmt.Println("not found")}err = fetch(500)var httpErr *HTTPErrorif errors.As(err, &httpErr) {fmt.Println("status:", httpErr.Status)}// Unwrap вручнуюunwrapped := errors.Unwrap(fmt.Errorf("wrap: %w", ErrNotFound))fmt.Println(unwrapped == ErrNotFound) // true}
Как отвечать на собеседовании
Начните с назначения пакета: создание, обёртывание и проверка ошибок. Затем перечислите ключевые функции и их сценарии. Обязательно приведите пример, где errors.Is и errors.As применяются в реальном коде. Подчеркните, что пакет появился в Go 1.13 и стал стандартом, заменив ручные проверки. Если спросят про errors.Join, упомяните его для агрегации ошибок. Говорите кратко, без лишней теории, но покажите, что понимаете цепочку ошибок и разницу между значением и типом.
Что проверяет интервьюер
Интервьюер оценивает:
- знание базовых функций пакета и их назначения;
- понимание разницы между
errors.Isиerrors.As; - умение работать с цепочками ошибок через
%wиUnwrap; - знание sentinel errors и практик их использования;
- способность объяснить, когда использовать
errors.New, а когдаfmt.Errorf.
Типичные ошибки
- Сравнение ошибок через
==вместоerrors.Is- ломается при обёртывании. - Использование
errors.Asдля проверки значения, а не типа. - Забывают, что
errors.Newсоздаёт уникальную ошибку, и пытаются сравнивать тексты. - Не используют
%wвfmt.Errorf, теряя цепочку ошибок. - Путают
errors.Isиerrors.Asместами. - Не проверяют, что
errors.Asзаписывает результат в указатель на тип, а не в сам тип.
> Похожие задачи по Go
Как реализовать worker pool для ограничения количества горутин в Go
Как программа узнает об окончании списка URL и передает сигнал завершения
Как реализуется раздача заданий и синхронизация горутин в воркерпуле в Go
Для чего нужен type switch в Go
> Похожие задачи по backend
Как реализовать worker pool для ограничения количества горутин в Go
Как программа узнает об окончании списка URL и передает сигнал завершения
Как реализуется раздача заданий и синхронизация горутин в воркерпуле в Go
Для чего нужен type switch в Go
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью