Go-контексты без боли — как понять context.Context и зачем он везде
Разбираем, почему context.Context встречается почти в каждой функции на Go, как он спасает от зависаний и управляет временем жизни операций.
Go-разработчики быстро привыкают к синтаксису: функции, интерфейсы, ошибки. Но почти сразу после "Hello, world" в коде начинает появляться что-то загадочное — context.Context. И не просто где-то в глубине пакета, а прямо в сигнатуре каждой второй функции. Зачем он нужен и почему без него никуда?
Давайте разберёмся.

Что такое context в Go
context.Context — это специальный объект, который передаётся по цепочке вызовов и управляет:
временем жизни операций,
отменой процессов,
дедлайнами,
передачей метаданных (например, ID запроса).
Контекст — это как "невидимый рюкзак", который функция получает вместе с вызовом и из которого можно достать полезную информацию.
Где чаще всего встречается context
Работа с сетевыми запросами — отмена по таймауту, если ответ слишком долго не приходит.
Запросы к БД — чтобы не держать соединение "висящим" бесконечно.
Фоновые горутины — graceful shutdown при завершении сервиса.
Почему он почти в каждом аргументе
Go придерживается принципа: явное лучше неявного. Вместо глобальных переменных или скрытых сигналов, функции прямо получают контекст. Это делает код предсказуемым и даёт контроль на верхнем уровне — откуда стартует запрос.
func fetchUser(ctx context.Context, id int) (User, error) {
row := db.QueryRowContext(ctx, "SELECT name FROM users WHERE id=?", id)
...
}Если запросу поставили ctx с таймаутом, то любая операция внутри автоматически остановится по истечении времени.

Важные приёмы работы
Создание контекста с таймаутом:
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()Отмена вручную:
ctx, cancel := context.WithCancel(context.Background())
go func() {
time.Sleep(time.Second)
cancel() // остановим работу всех, кто слушает этот ctx
}()Передача значений (аккуратно!):
ctx = context.WithValue(ctx, "requestID", "abc123")Важно: злоупотреблять WithValue не стоит — это скорее "метаданные", а не полноценные данные.
Типичные ошибки и ловушки
Не вызвали
cancel()→ утечка ресурсов.Пихаем всё подряд в
WithValue→ теряется читаемость.Не передаём context дальше → лишаем функцию возможности управлять собой.
Главная идея context проста: контроль должен быть у вызывающего кода, а не у вызываемого. Именно поэтому в Go почти каждая публичная функция в пакете стандартной библиотеки начинается с аргумента ctx.
Контекст — это не просто модное слово в Go. Это встроенный инструмент, который делает ваши программы предсказуемыми, управляемыми и защищёнными от зависаний. Чем раньше начнёте правильно его использовать — тем меньше "боли" в будущем.
У Кодика появился новый топовый курс по Go 🚀
Это мощный и понятный старт для тех, кто хочет освоить язык, на котором пишут быстрые и надёжные сервисы. В курсе простыми словами объясняем всё: от первых шагов до серьёзных концепций вроде горутин и контекстов.
А ещё у нас есть уютный telegram-канал, где мы делимся новостями из мира IT, разбираем интересные задачи и общаемся с комьюнити. Подписывайся, чтобы не пропускать самое важное.