It's a core concept of Go's channels (or other CSP implementations such as Clojure's core.async library) that they are blocking. In general, as you already mentioned, there're two types of channels:
- buffered which block if the buffer is full.
- unbuffered which block if there's no "rendezvous", i.e. there must be someone who puts (
c <-
) to and someone who takes (<- c
) from the channel.
In your particular case the Go runtime is smart enough to detect that there's no one who will ever take 3
from channel c
. Hence, it's a deadlock and (thankfully) an error is thrown.
What you typically do when you're working with channels is using goroutines (checkout this introduction) which spawn a lightweight thread—managed by the Go runtime—to execute the body concurrently:
c := make(chan int)
go func() { c <- 3 }() // Create a new gorountine that puts 3 to the channel
fmt.Println(<- c) // Take 3 from the channel and print it in the main thread