Go

What are directional channel types and why use them?

Question 197MediumGo 1.22 to 1.25

chan<- T is send-only and <-chan T is receive-only. A bidirectional chan T converts implicitly to either one, but you can't convert back. The compiler rejects receiving from a send-only channel and sending to a receive-only one. It also rejects close on a receive-only channel, which enforces "the receiver never closes".

func producer(out chan<- int) {
	defer close(out) // allowed: sender side
	for i := range 3 { out <- i }
}

func consumer(in <-chan int) {
	for v := range in { fmt.Println(v) }
	// close(in) // compile error: cannot close receive-only channel
}

func main() {
	ch := make(chan int)
	go producer(ch)
	consumer(ch)
}

Why it matters: the types document ownership in the API. A function that returns <-chan T (the generator pattern) keeps the ability to send and close to itself. Read the arrow as binding to the leftmost chan: chan<- chan int is a send-only channel of bidirectional channels, while chan (<-chan int) needs parentheses.

More on Channels & select

All 38 Channels & select questions