Первый и самый простой это пустая структура. Она не занимает памяти и означает только одно: событие произошло:
done := make(chan struct{})
go func() {
// работа выполнена
close(done)
}()
<-done // ждём сигналаclose — лучший способ сигналить завершение, потому что все читатели получат сигнал одновременно.Второй способ это передать булево значение или ошибку, когда важно передать не только факт события, но и его результат:
result := make(chan error, 1)
go func() {
err := doSomething()
result <- err
}()
if err := <-result; err != nil {
log.Fatal(err)
}
Третий способ —
context.Context. Это стандарт в продакшн-коде. Контекст несёт в себе сигнал отмены, дедлайн и значения. Внутри он тоже использует канал:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
select {
case result := <-work(ctx):
fmt.Println(result)
case <-ctx.Done():
fmt.Println("timeout:", ctx.Err())
}
🐸 Библиотека Go для собеса