我正在尝试创建一个程序,每 3 日、8 日打印一次 "Eat"
、"Work"
、"Sleep"
,和第 24 秒。这是我的代码:
package main
import (
"fmt"
"time"
)
func Remind(text string, delay time.Duration) <-chan string { //channel only for receiving strings
ch := make(chan string) // buffered/unbuffered?
go func() {
for {
msg := "The time is " + time.Now().Format("2006-01-02 15:04:05 ") + text
ch <- msg
time.Sleep(delay) // waits according to specification
}
}()
return ch
}
func main() {
ch1 := Remind("Eat", 1000*1000*1000*3) // every third second
ch2 := Remind("Work", 1000*1000*1000*8) // every eighth second
ch3 := Remind("Sleep", 1000*1000*1000*24) // every 24th second
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
它的问题是它在打印时间后立即停止运行,然后是 “Eat”
。在我读过的其他示例中,select
语句会一直持续下去。为什么现在不呢?
最佳答案
我不知道您在哪里读到过 select
会永远持续下去,但事实并非如此。
一旦 case
被执行,select
语句就“完成”了。如果 case
中指定的通信操作都不能继续并且没有default
分支,select
将阻塞,只要任何 com。操作可以继续。但是一旦一个case
被执行,select
就不会重复了。
阅读规范中的相关部分:Select statements .
把它放在无穷无尽的 for
中,让它永远重复:
for {
select { // chooses one channel that is not empty. Should run forever (?)
case rem1 := <-ch1:
fmt.Println(rem1)
case rem2 := <-ch2:
fmt.Println(rem2)
case rem3 := <-ch3:
fmt.Println(rem3)
}
}
作为旁注:
您可以创建 time.Duration
使用 time
中的常量值更容易包裹:
ch1 := Remind("Eat", 3*time.Second) // every third second
ch2 := Remind("Work", 8*time.Second) // every eighth second
ch3 := Remind("Sleep", 24*time.Second) // every 24th second
您可能还想查看 time.Ticker
用于与您的 Remind()
函数类似的任务的类型。
关于select - 戈朗 : select statement exits when it shouldn't,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36327358/