Given the below function using an unbuffered channel:
1 func main() {
2 c := make(chan int)
3 c <- 17
4 fmt.Println(<- c)
5 }
Execution order: line 3 -> line 4
Line 3 -> no receiver detected -> the channel is waiting for a receiver and the program can't execute line 4 => deadlock occurs: the program blocks forever
With goroutine:
1 func main() {
2 c := make(chan int)
3 go () {
4 c <- 17
5 }()
6 fmt.Println(<- c)
7 }
Execution order: line 3 -> line 6 -> line 4 -> line 6
Line 3: no receiver detected but it spawns a goroutine running in the background
Line 6: a receiver detected -> line 4 is executed -> line 6 is executed => no deadlock
With a buffered channel:
1 func main() {
2 c := make(chan int, 1)
3 c <- 17
4 fmt.Println(<- c)
5 }
Execution order: line 3 -> line 4
Line 3: the buffered channel isn't overfilled when number 17 was being sent to it -> the receiver isn't blocked
Line 4: the receiver works as expected as it's not blocked => no deadlock