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とか)