Concurrency · 3 MIN READ
The arrow in the type is who may send
Write a producer that takes chan<- int and closes it.
The Tour writes ch <- v and v := <-ch and then, in Effective Go, the type itself carries the arrow: chan<- int is send-only, <-chan int is receive-only. A function that only produces values should take chan<- T. The compiler then refuses a receive in that body, which is the whole point — the restriction is the API.
Conversion is one way: a bidirectional channel may be passed where a directional one is wanted. The other direction does not compile. Close is a send-side operation, so it belongs on chan<- T.
SEE THE IDEA
The type limits who may send or receive
- 01
Owner
gochan intCan send, receive and close
- 02
Producer parameter
gochan<- intMay send and close
- 03
Consumer parameter
go<-chan intMay receive only
A bidirectional channel can be passed to a directional parameter.
In practice
Use direction in function signatures to communicate roles and let the compiler reject accidental reverse operations. The owner still needs a runtime lifecycle rule: a send-only parameter can close a channel, but that ability does not establish that it is the correct owner to do so.
Watch out
Direction is a permission, not an ownership guarantee. Two senders can still race to close unless the design assigns one closer.
Work through the exercise
package main
// Produce sends every value and then closes out. The parameter
// is send-only: a receive in this function should not compile.
func Produce(out chan<- int, values []int) {}
func main() {}Trace each value and write down your reasoning. Copy the source into GopherForge or your local Go environment to compile and check it. This web page does not execute your code or send it to a compiler service.
Progress stays in this browser. No account needed.