Why the default in select running one more time

package main

import "fmt"
import "time"

func main() {
	ch := make(chan int, 1)
	x := 0

	time.AfterFunc(10*time.Second, func() {
		fmt.Println("10 seconds over....")
		ch <- 8
	})

	for {
		select {
		case n := <-ch:
			fmt.Println(n, "is arriving")
			fmt.Println("done")
			return
		default:
			x += 3
			time.Sleep(3 * time.Second)
			fmt.Println(x, "time to wait")
		}
	}
}

3 time to wait
6 time to wait
9 time to wait
10 seconds over…
12 time to wait
8 is arriving
done

I think “12 time to wait” should not be printed and ‘8 is arriving’ should directly after ‘10 seconds over…’

Look at the order of these statements:

x += 3
time.Sleep(3 * time.Second)
fmt.Println(x, "time to wait")

It first increases x, then sleeps, then prints the “time to wait message”.
When the program starts (at time 0s) it sleeps (from time 0s to 3s) and prints "3 time to wait".
After that it sleeps again (from time 3s to 6s) and prints 6 time to wait.

The message "12 time to wait" is printed after sleeping from time 9s to 12s. That’s why if falls asleep before the "10 seconds over...." time.

1 Like

Thank you for your reply.