To add to nos' answer, you can simulate that case (where "test2 <- true" is run at the moment which is just between the first iteration and the second iteration") easily enough by making your first message reception (case <- test) wait one second.
case <-test:
log.Println("test")
time.Sleep(1 * time.Second)
By the time the anonymous goroutine wakes up, main() has already sent its two messages to the two buffered channel (buffer means non-blokcing for one message), and exited.
If main() exits, everything else, including the goroutine which was busy sleeping, stops.
See play.golang.org: the output would be:
2009/11/10 23:00:00 test
You wouldn't have the time to see test2.
In order to make sure your goroutine can process both message, you need:
main() to wait for said goroutine to finish. That is where the sync package comes into play, using (for instance, this isn't the only solution) a WaitGroup directive.
var wg sync.WaitGroup
wg.Add(1)
go func() {
// Decrement the counter when the goroutine completes.
defer wg.Done()
...
}
... // end of main():
// Wait for goroutine to complete.
wg.Wait()
the goroutine to actually exit at some time (instead of being stuck in the for loop forever). See "In Go, does a break statement break from a switch/select?"
loop: <==========
for {
select {
case <-test:
log.Println("test")
time.Sleep(1 * time.Second)
case <-test2:
log.Println("test2")
break loop <==========
}
}
See play.golang.org: the message test2 is sent while the goroutine is sleeping after test1, but main() will wait (wg.Wait()), and the goroutine will have its chance to read and print test2 one second later.
The output is:
2009/11/10 23:00:00 test
2009/11/10 23:00:01 test2 // one second later