Closing a channel tells a range loop when no more values are coming.

close channel A `for range` loop over a channel stops after the channel is closed and drained.

Close and Range

extra
close_range.go
Replay: real traced execution (multi-file project)
package main

import "fmt"

func main() {
	var extra = "gamma"
	stream := make(chan string, 3)

	stream <- "alpha"
	stream <- "beta"
	stream <- extra
	close(stream)

	count := 0
	for item := range stream {
		count++
		fmt.Println("item=", item)
	}
	fmt.Println("count=", count)
}
package main

import "fmt"

func main() {
	var extra = "delta"
	stream := make(chan string, 3)

	stream <- "alpha"
	stream <- "beta"
	stream <- extra
	close(stream)

	count := 0
	for item := range stream {
		count++
		fmt.Println("item=", item)
	}
	fmt.Println("count=", count)
}
package main

import "fmt"

func main() {
	var extra = "omega"
	stream := make(chan string, 3)

	stream <- "alpha"
	stream <- "beta"
	stream <- extra
	close(stream)

	count := 0
	for item := range stream {
		count++
		fmt.Println("item=", item)
	}
	fmt.Println("count=", count)
}
  1. extra ← "gamma", stream ← (chan string)(⟨addr A⟩), count ← 0

    5func main() {6  var extra→ "gamma" = "gamma" //@extra="delta", "omega"7  stream→ (chan string)(⟨addr A⟩) := make(chan string, 3)89  stream(chan string)(⟨addr A⟩) <- "alpha"10  stream(chan string)(⟨addr A⟩) <- "beta"11  stream(chan string)(⟨addr A⟩) <- extra"gamma"12  close(stream(chan string)(⟨addr A⟩))1314  count→ 0 := 015  for item := range stream {
  2. count ← 1

    pass 1 of 3
    14count := 015for item"alpha" := range stream(chan string)(⟨addr A⟩) {16  count→ 1++17  fmt.Println("item=", item"alpha")18}
    outputitem= alpha
    All 3 passes — pass 1 is the card above
    passitemcount
    1"alpha"0 1
    2"beta"1 2
    3"gamma"2 3
  3. fmt.Println("count=", count)

    18  }19  fmt.Println("count=", count3)20}
    outputcount= 3
  1. extra ← "delta", stream ← (chan string)(⟨addr A⟩), count ← 0

    5func main() {6  var extra→ "delta" = "delta"7  stream→ (chan string)(⟨addr A⟩) := make(chan string, 3)89  stream(chan string)(⟨addr A⟩) <- "alpha"10  stream(chan string)(⟨addr A⟩) <- "beta"11  stream(chan string)(⟨addr A⟩) <- extra"delta"12  close(stream(chan string)(⟨addr A⟩))1314  count→ 0 := 015  for item := range stream {
  2. count ← 1

    pass 1 of 3
    14count := 015for item"alpha" := range stream(chan string)(⟨addr A⟩) {16  count→ 1++17  fmt.Println("item=", item"alpha")18}
    outputitem= alpha
    All 3 passes — pass 1 is the card above
    passitemcount
    1"alpha"0 1
    2"beta"1 2
    3"delta"2 3
  3. fmt.Println("count=", count)

    18  }19  fmt.Println("count=", count3)20}
    outputcount= 3
  1. extra ← "omega", stream ← (chan string)(⟨addr A⟩), count ← 0

    5func main() {6  var extra→ "omega" = "omega"7  stream→ (chan string)(⟨addr A⟩) := make(chan string, 3)89  stream(chan string)(⟨addr A⟩) <- "alpha"10  stream(chan string)(⟨addr A⟩) <- "beta"11  stream(chan string)(⟨addr A⟩) <- extra"omega"12  close(stream(chan string)(⟨addr A⟩))1314  count→ 0 := 015  for item := range stream {
  2. count ← 1

    pass 1 of 3
    14count := 015for item"alpha" := range stream(chan string)(⟨addr A⟩) {16  count→ 1++17  fmt.Println("item=", item"alpha")18}
    outputitem= alpha
    All 3 passes — pass 1 is the card above
    passitemcount
    1"alpha"0 1
    2"beta"1 2
    3"omega"2 3
  3. fmt.Println("count=", count)

    18  }19  fmt.Println("count=", count3)20}
    outputcount= 3