Looking through some code I found two ways of doing something every second:
for {
fmt.Println("This is printed every second")
time.Sleep(time.Second * 1)
}
and
for {
select {
case <-time.After(time.Second * 1):
fmt.Println("This is printed every second")
}
}
Apart from the first one being more readable (in my opinion), what are the advantages of one over the other?
There are (at least) two reasons you might want to do that:
time.Sleep
always blocks your current goroutine, while waiting on a channel might not if you include a default case: timeoutCh := time.After(time.Second)
LOOP:
for {
select {
case <-timeoutCh:
break LOOP
default:
}
// do some work
}
opNotifyCh := op()
select {
case res := <-opNotifyCh:
fmt.Println("Op finished with result:", res)
case <-time.After(time.Second):
fmt.Println("Op timed out")
}
time.After
gives you a channel. You can do whatever you want with it - you can pass it to a function, you can return it to a caller, you can put it in a struct - anything, really. This gives you a lot of freedom.