Golang chan keyword
last modified May 7, 2025
This tutorial explains how to use the chan
keyword in Go. We'll
cover channel basics with practical examples of concurrent programming.
The chan keyword declares a channel type for communication between goroutines. Channels are typed conduits that let you send and receive values.
In Go, chan
is fundamental for safe concurrent programming. Channels
synchronize goroutines and prevent race conditions by design.
Basic channel creation
The simplest use of chan
creates an unbuffered channel. This example
demonstrates basic channel declaration and usage.
package main import "fmt" func main() { // Create an unbuffered channel of integers ch := make(chan int) go func() { // Send value through channel ch <- 42 }() // Receive value from channel val := <-ch fmt.Println("Received:", val) }
The channel ch
transmits an integer between goroutines. The main
goroutine blocks until the value is received.
Buffered channels
Buffered channels allow sending multiple values without blocking. This example shows how to create and use them.
package main import "fmt" func main() { // Create a buffered channel with capacity 3 ch := make(chan string, 3) // Send values without blocking ch <- "first" ch <- "second" ch <- "third" // Receive values fmt.Println(<-ch) fmt.Println(<-ch) fmt.Println(<-ch) }
The channel holds three strings before blocking. Values are received in FIFO order. Buffered channels decouple senders and receivers.
Channel directions
Channel parameters can be restricted to send-only or receive-only. This example demonstrates directional channels.
package main import "fmt" // sendOnly can only send to channel func sendOnly(ch chan<- int, val int) { ch <- val } // receiveOnly can only receive from channel func receiveOnly(ch <-chan int) int { return <-ch } func main() { ch := make(chan int) go sendOnly(ch, 99) val := receiveOnly(ch) fmt.Println("Received:", val) }
Directional channels make function contracts clearer. chan<-
is
send-only, while <-chan
is receive-only.
Channel synchronization
Channels can synchronize goroutines. This example shows a common worker pattern.
package main import ( "fmt" "time" ) func worker(done chan bool) { fmt.Print("Working...") time.Sleep(time.Second) fmt.Println("done") done <- true } func main() { done := make(chan bool) go worker(done) // Block until worker finishes <-done fmt.Println("Worker completed") }
The main goroutine waits for the worker to signal completion. Channels provide simple synchronization without locks.
Select statement with channels
The select
statement handles multiple channel operations. This
example demonstrates non-blocking channel operations.
package main import ( "fmt" "time" ) func main() { ch1 := make(chan string) ch2 := make(chan string) go func() { time.Sleep(1 * time.Second) ch1 <- "one" }() go func() { time.Sleep(2 * time.Second) ch2 <- "two" }() for i := 0; i < 2; i++ { select { case msg1 := <-ch1: fmt.Println("Received", msg1) case msg2 := <-ch2: fmt.Println("Received", msg2) } } }
select
waits on multiple channel operations. It executes the first
ready case. This is useful for timeouts and multiplexing.
Channel timeouts
Channels can implement timeouts using select
. This example shows
how to prevent indefinite blocking.
package main import ( "fmt" "time" ) func main() { ch := make(chan string) go func() { time.Sleep(3 * time.Second) ch <- "result" }() select { case res := <-ch: fmt.Println(res) case <-time.After(2 * time.Second): fmt.Println("timeout") } }
time.After
creates a channel that sends after the duration. The
select chooses between the result and timeout.
Closing channels
Closing channels signals no more values will be sent. This example demonstrates proper channel closing.
package main import "fmt" func producer(ch chan int) { for i := 0; i < 5; i++ { ch <- i } close(ch) } func main() { ch := make(chan int) go producer(ch) for { val, ok := <-ch if !ok { fmt.Println("Channel closed") break } fmt.Println("Received:", val) } }
The producer closes the channel after sending all values. Receivers can detect closure using the second return value.
Source
This tutorial covered the chan
keyword in Go with practical
examples of channel usage in concurrent programming.
Author
List all Golang tutorials.