CodeNebula
Go⚡Concurrencyintermediate

Channels

Go · Concurrency · Run with go run

Explanation

Channels are typed, goroutine-safe communication pipes. `make(chan T)` creates an unbuffered channel — a send blocks until a receiver is ready, and vice versa. `make(chan T, n)` creates a buffered channel that holds up to `n` values without blocking. The rule: *Do not communicate by sharing memory; share memory by communicating.*

Real-World Scenario

A pipeline where a producer goroutine sends URLs to a channel, and a pool of consumer goroutines reads from it to fetch and process each URL concurrently — without any mutex or shared state.

Quick Snippet

snippet.go
// Unbuffered channel — synchronizes sender and receiver
ch := make(chan int)
go func() { ch <- 42 }() // sender blocks until receiver is ready
val := <-ch              // receiver blocks until sender sends
fmt.Println(val)         // 42

// Buffered channel — sender only blocks when buffer is full
buf := make(chan string, 3)
buf <- "a"
buf <- "b"
buf <- "c"
// buf <- "d" would block here

// Close signals no more values; range drains the channel
close(buf)
for s := range buf {
    fmt.Println(s) // a, b, c
}

Full Example

channels.go
// Compile: go run channels.go
// Output:
//   received: 42
//   a
//   b
//   c
package main

import "fmt"

func main() {
	// Unbuffered channel — synchronizes sender and receiver
	ch := make(chan int)
	go func() { ch <- 42 }()
	fmt.Println("received:", <-ch)

	// Buffered channel — sender does not block until buffer full
	buf := make(chan string, 3)
	buf <- "a"
	buf <- "b"
	buf <- "c"

	close(buf)
	for s := range buf {
		fmt.Println(s)
	}
}
Run command
go run channels.go