Go

Can you compare channels with ==, use them as map keys, and send channels over channels?

Question 215MediumGo 1.22 to 1.25

Yes to all three. Channel types are comparable: two channel values are equal if they came from the same make call (the same hchan pointer) or are both nil. So channels can be map keys and comparable type arguments, and you can use them in switch.

subs := map[chan Event]struct{}{}   // pub/sub subscriber set

func (b *Bus) Unsubscribe(ch chan Event) {
	b.mu.Lock()
	defer b.mu.Unlock()
	if _, ok := b.subs[ch]; ok {
		delete(b.subs, ch)
		close(ch) // bus owns the subscriber channels it created
	}
}

Channels are first-class values, so chan chan T works too (the reply-channel pattern). Conversions between directions work only one way: a chan T is assignable to <-chan T, not the reverse. Because of that assignability, c == r compiles for c chan T and r <-chan T, and you can look up a map[<-chan T]V using a chan T. The trap is interfaces: any(c) == any((<-chan T)(c)) is false, because the dynamic types differ even though the underlying channel is the same. Keep key types consistent when keys pass through any.

More on Channels & select

All 38 Channels & select questions