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:

main.go

	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)

Output:

received from channel: foo
range loop finished because ch was closed

A receive from closed channels returns zero value immediately:

main.go

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

Output:

Receive from closed channel immediately returns zero value of the type: ""

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

main.go

	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)

Output:

received 8, is channel closed: false
received 0, is channel closed: true

Closing channel twice panics:

main.go

	ch := make(chan string)
	close(ch)
	close(ch)

Output:

panic: close of closed channel

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

Sending to closed channel panics:

main.go

	ch := make(chan int)
	close(ch)
	ch <- 5 // panics

Output:

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