Introduction to Go Channels: Types, Operations, Rules, and Practical Examples
This article explains Go's channel feature, covering its design philosophy, channel types (bidirectional and directional), core operations such as send, receive, close, capacity queries, detailed execution rules for different channel states, and includes several illustrative code examples.
Go provides two fundamental built‑in concurrency primitives—goroutine and channel—and this article focuses on channels, translating and expanding the original Go101 material for easier learning.
Rob Pike famously said, "Do not communicate by sharing memory; instead, share memory by communicating," and channels were created to embody this principle.
A channel is a composite type (like array, slice, map) that carries values of a single element type; it can be nil. Channels can be bidirectional ( chan T) or directional ( chan<- T for send‑only, <-chan T for receive‑only).
Creating a channel uses the built‑in make function, e.g., c := make(chan int, 2), where the optional second argument sets the buffer capacity (default 0 for an unbuffered channel).
Channel operations include:
Closing a channel with close(c) (panic if the channel is nil, already closed, or a send‑only channel).
Sending a value: c <- v (panic if the channel is closed; blocks if the buffer is full).
Receiving a value: v, ok := <-c (ok is false when the channel is closed and empty).
Querying capacity with cap(c) and length with len(c).
The runtime maintains three internal queues for a channel: the receiving‑goroutine queue (RGQ), the sending‑goroutine queue (SGQ), and the value‑buffer queue (VBQ). The interaction of these queues determines whether send/receive operations block or proceed.
Four rule scenarios (A‑D) describe the exact steps the scheduler follows when a goroutine attempts to receive from, send to, or close a channel, covering cases such as empty/non‑empty buffers, nil channels, and closed channels.
Practical examples demonstrate unbuffered and buffered channel usage, a perpetual “football match” simulation using multiple goroutines, and the for‑range loop over a channel, which continues until the channel is closed and its buffer emptied.
All value transfers through a channel involve copying, similar to assignment or function argument passing; large values should be sent via pointers to avoid excessive copying.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
360 Tech Engineering
Official tech channel of 360, building the most professional technology aggregation platform for the brand.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
