为什么在go例程中关闭通道会导致接收通道接收值?

I have a go routine that periodically polls every interval and does a action. It also checks for done channel, as a end signal, to stop the polling.

  go func(){
       for {
          select{
              case <-myticker.C:
                 do_something()
              case <-done:
                 fmt.Println("I am done")
                 return
         } 
       }

    }

I realized that if I close the channel, It also runs as if the value is passed to done channel, It prints out "I am done" Why is that so?

From the spec:

A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.

See https://golang.org/ref/spec#Receive_operator.

Because it can't finish without returning values. So it has to return some "stub", according to spec zero value was chosen. Also you may use two-value form to check whether real value was returned or a stub.

val, ok := <- someChannel
if ok {
   // value was got from the channel
}
if !ok {
   // channel was closed
}