I am reading 'Concurrency in Go' and have found this example of goroutine leaks:
func main() {
var wg sync.WaitGroup
doWork := func(strings <-chan string) <-chan interface{} {
completed := make(chan interface{})
go func() {
defer fmt.Println("doWork exited.")
defer close(completed)
defer wg.Done()
fmt.Println("a")
for s := range strings {
fmt.Println(s)
}
fmt.Println("b")
}()
return completed
}
wg.Add(1)
doWork(nil)
fmt.Println("Waiting")
wg.Wait()
fmt.Println("Done.")
}
The
strings
channel will never gets any strings written onto it, and the goroutine containingdoWork
will remain in memory for the life time of process.
I don't understand - why ?
How I understand this code:
-
As
strings
isnil
range
-loop just skipped. As any range overnil
:slice := []int{10, 20, 30, 40, 50} slice = nil for i := range slice { fmt.Println(i) } fmt.Println("Done")
fmt.Println("doWork exited.")
will be executed-
close(completed)
will be executed
But I see it works like that. Why ?