Почему нельзя закрыть канал, возвращаемый ctx.Done(), через функцию close()?

Канал, возвращаемый ctx.Done() в Go, нельзя закрывать вручную через close(), потому что этот канал управляется самим контекстом.

Короткий ответ

Что ответить на собеседовании

Канал, возвращаемый ctx.Done() в Go, нельзя закрывать вручную через close(), потому что этот канал управляется самим контекстом.

Подробный разбор

Ответ с пояснениями

Канал, возвращаемый ctx.Done() в Go, нельзя закрывать вручную через close(), потому что этот канал управляется самим контекстом.

Причины:

  • Канал Done() создаётся и закрывается внутри реализации контекста, чтобы сигнализировать об отмене операции.
  • Если пользователь попытается закрыть этот канал самостоятельно, это приведёт к панике (panic), так как канал может быть уже закрыт или закрыт в другом месте.
  • Контекст гарантирует, что канал будет закрыт ровно один раз, когда отмена произойдёт.

Правильный способ работы с ctx.Done() — только читать из канала, чтобы реагировать на отмену, но не пытаться его закрывать.

Пример:

ctx, cancel := context.WithCancel(context.Background())

// Запускаем горутину, которая слушает отмену
go func() {
    <-ctx.Done()  // ждем сигнал отмены
    fmt.Println("Context cancelled")
}()

// Отмена контекста
cancel()

Таким образом, управление жизненным циклом канала Done() полностью на стороне контекста, и вмешательство пользователя запрещено.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее