time.Tick とは?
-
time.Tick(<Duration>)
は 指定した間隔で時刻を配信する同期チャネル を返す関数-
tick := time.Tick(time.Millisecond)
した場合のtick
は1ms間隔で時刻を送信する
-
- 通常のチャネル同様に
<-tick
で受ける - チャネルなので
select case
文やfor t := range tick { ... }
文で受信処理が可能
select caseでTickを受ける場合
- 結論から言うと
select case
でTickを受ける場合はdefault
節は書かないように!
default節なし
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(time.Millisecond * 1)
go func() {
for {
select {
case t := <-tick:
fmt.Println("ticked", t)
}
}
}()
time.Sleep(time.Second)
}
- デモはこちら → http://play.golang.org/p/5OAsXaNXRB
- 期待通り、1ms毎にメッセージとTickから受信した時刻が出力される
default節あり
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(time.Millisecond * 1)
go func() {
for {
select {
case t := <-tick:
fmt.Println("ticked", t)
default:
fmt.Println("unticked")
}
}
}()
time.Sleep(time.Second)
}
- デモはこちら → http://play.golang.org/p/i3IwSN2cT3
- Tickから受信するcase節が全く処理されず、
default
節の"unticked"ログがひたすら出力され続ける
推測
- Tickを受けるselect caseに
default
節を記述した場合、処理が走った その瞬間のタイミング で送受信可能なチャネルが無いとdefault
節の処理が走る - Tickに限らず、時刻配信系のチャネルは同様かも(
time.After
とか)