Go

Who should close a channel, and why? What are the rules?

Question 188MediumGo 1.22 to 1.25

The rule: the sender closes, never the receiver, and only when there are no more sends. Closing is a broadcast message that says "no more values". A receiver closing the channel would cause a sender panic (send on closed channel) and races with in-flight sends.

  • One sender: that sender closes, usually with defer close(out).
  • Many senders: no single sender may close. Use a coordinator: a sync.WaitGroup and a separate goroutine that waits and then closes.
  • Receivers wanting to stop senders: don't close the data channel. Signal through a separate done channel or context.
  • Closing is not required for garbage collection. An unreferenced channel is collected whether it is closed or not. Close only when receivers need the signal, for example to end a range.
func merge[T any](cs ...<-chan T) <-chan T {
	out := make(chan T)
	var wg sync.WaitGroup
	for _, c := range cs {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for v := range c {
				out <- v
			}
		}()
	}
	go func() { wg.Wait(); close(out) }() // single owner closes
	return out
}

More on Channels & select

All 38 Channels & select questions