Ответ
Для сигнализации через каналы, когда не требуется передавать данные, самым идиоматичным и эффективным подходом в Go является использование пустой структуры — struct{}
. Таким образом, тип канала будет chan struct{}
.
Почему именно chan struct{}
?
- Эффективность по памяти: Тип
struct{}
не содержит полей, поэтому переменная этого типа не занимает в памяти места (0 байт). Это самый легковесный тип данных, который можно использовать для сигнала. - Ясность намерения: Использование
chan struct{}
явно говорит читателю кода, что канал используется исключительно для передачи сигнала, а не для обмена данными. Значение, передаваемое по каналу, не имеет значения — важен сам факт отправки/получения.
Пример: Сигнал о завершении работы
// Используем буферизированный канал, чтобы отправляющая горутина
// не блокировалась, если принимающая сторона еще не готова.
done := make(chan struct{}, 1)
go func() {
// ... выполняем какую-то полезную работу ...
fmt.Println("Горутина завершила работу, отправляю сигнал.")
// Отправляем пустую структуру как сигнал о завершении
done <- struct{}{}
}()
// Основная горутина блокируется, ожидая сигнала
<-done
fmt.Println("Основная горутина получила сигнал и завершается.")
Сравнение с альтернативами:
chan bool
: Работает, но менее эффективно. Типbool
занимает 1 байт памяти. Передача значенияtrue
илиfalse
избыточна, так как сам факт получения данных из канала уже является сигналом.chan int
: Еще более избыточен. Занимает 4 или 8 байт (в зависимости от архитектуры) и не несет дополнительной смысловой нагрузки для простой сигнализации.