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:
- A send to a nil channel blocks forever.
var ch chan int
ch <- 1 // This will block forever
- A receive from a nil channel blocks forever.
var ch chan int
<-ch // This will block forever
- A send to a closed channel panics.
ch := make(chan int)
close(ch)
ch <- 1 // This will panic
- A receive from a closed channel returns the zero value immediately.
ch := make(chan int)
close(ch)
val := <-ch // val is 0
- 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
- 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
- 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
- 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
- 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.