Closing channels

suggest change

You can close a channel with close(chan).

Main purpose of closing a channel is to notify worker goroutines that their work is done and they can finish.

This ensures you don’t leak goroutines.

Closing a channel ends range loop over it:

ch := make(chan string)

go func() {
	for s := range ch {
		fmt.Printf("received from channel: %s\n", s)
	}
	fmt.Print("range loop finished because ch was closed\n")
}()

ch <- "foo"
close(ch)
received from channel: foo
range loop finished because ch was closed

A receive from closed channels returns zero value immediately:

ch := make(chan string)
close(ch)
v := <-ch
fmt.Printf("Receive from closed channel immediately returns zero value of the type: %#v\n", v)
Receive from closed channel immediately returns zero value of the type: ""

When receiving, you can optionally test if channel is closed:

ch := make(chan int)
go func() {
	ch <- 8
	close(ch)
}()
v, isOpen := <-ch
fmt.Printf("received %d, is channel closed: %v\n", v, !isOpen)
v, isOpen = <-ch
fmt.Printf("received %d, is channel closed: %v\n", v, !isOpen)
received 8, is channel closed: false
received 0, is channel closed: true

Closing channel twice panics:

ch := make(chan string)
close(ch)
close(ch)
panic: close of closed channel

goroutine 1 [running]:
main.main()
	/tmp/src046648690/main.go:9 +0x57
exit status 2

Sending to closed channel panics:

ch := make(chan int)
close(ch)
ch <- 5 // panics
panic: send on closed channel

goroutine 1 [running]:
main.main()
	/tmp/src045382697/main.go:9 +0x63
exit status 2

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents