The Go Channel Axioms

Posted May 13, 2023 by Rohith ‐ 2 min read

In Go, channels are a fundamental primitive for concurrent communication and synchronization between goroutines. There are several axioms that govern how channels work in Go

The Go Channel Axioms are a set of principles that describe the behavior of channels in Go. They are:

  1. A send to a nil channel blocks forever.
var ch chan int
ch <- 1 // This will block forever

  1. A receive from a nil channel blocks forever.
var ch chan int
<-ch // This will block forever

  1. A send to a closed channel panics.
ch := make(chan int)
close(ch)
ch <- 1 // This will panic

  1. A receive from a closed channel returns the zero value immediately.
ch := make(chan int)
close(ch)
val := <-ch // val is 0

  1. The order of sends and receives on a channel is preserved.
ch := make(chan int)
go func() {
    ch <- 1
    ch <- 2
    ch <- 3
}()
fmt.Println(<-ch, <-ch, <-ch) // This will print 1 2 3

  1. If the channel buffer is full, a send blocks until space is available.
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3 // This will block until a value is removed from the buffer

  1. If the channel buffer is empty, a receive blocks until a value is available.
ch := make(chan int, 2)
ch <- 1
ch <- 2
val := <-ch
fmt.Println(val) // This will print 1
val = <-ch
fmt.Println(val) // This will print 2
val = <-ch // This will block until a value is added to the buffer

  1. A send on a channel happens before the corresponding receive from that channel completes.
ch := make(chan int)
go func() {
    ch <- 1
}()
val := <-ch // This will always receive the value 1

  1. Closing a channel happens before a receive that returns a zero value.
ch := make(chan int)
go func() {
    close(ch)
}()
val := <-ch // val is 0, because the channel was closed before sending a value

These axioms provide a set of guidelines for how channels behave in Go, and can help you write correct and predictable concurrent code.

quick-references blog go

Subscribe For More Content