Exchanging values through sends and receives

Concurrent activities need to exchange data, and channels provide an object and operations for that exchange. Go channels specify an element type and can restrict an interface to sending or receiving, expressing communication direction in the type.

Go permits multiple goroutines to operate on one channel. Values can nevertheless retain references to shared data, whose subsequent use needs its own discipline. Channel communication does not automatically turn the entire reachable object graph into private copies.

References: [1]

Capacity changes when operations wait

An unbuffered Go channel requires a ready sender and receiver; a buffered channel permits a send while not full and a receive while not empty. Capacity changes synchronization as well as storage, not merely a performance setting.

A nil channel is never ready for communication, while a closed channel has a different lifecycle state. A receive can report whether its value was sent before closure. Protocols must distinguish no available data, no ready peer, and closure rather than treating them as one ordinary empty result.

References: [1]

Communication establishes specified synchronization

The Go memory model relates a send to completion of its corresponding receive. Unbuffered channels also impose a relation from receiving to completion of the send. Adding buffering can invalidate reasoning that depended on the original rendezvous ordering.

Select chooses among communication operations that can proceed. If several are ready, the language’s selection rule applies rather than an automatic source-order priority. A correct protocol must account for transmitted values, waiting relationships, and selection together.

References: [2] [1]