Go 如果在计时器通道过期后再次尝试从其接收,会发生什么情况
我正在玩围棋教程中的一个。我对代码进行了如下编辑:Go 如果在计时器通道过期后再次尝试从其接收,会发生什么情况,go,Go,我正在玩围棋教程中的一个。我对代码进行了如下编辑: package main import ( "fmt" "time" ) func main() { tick := time.Tick(100 * time.Millisecond) boom := time.After(500 * time.Millisecond) for { select { case <-tick: fmt.Pri
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
c, ok := <-boom
fmt.Println(c)
fmt.Println(ok)
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
fmt.Println("Finished")
}
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
.
.
tick.
BOOM!
c
和ok
永远不会打印,最后一个“完成”也永远不会打印。有人能帮我理解当我第二次尝试从频道接收时,会发生什么情况吗?想想什么时候。之后(引用自):
等待持续时间过后,然后发送当前时间
在返回的频道上
所以boom:=time.After(500*time.毫秒)
将返回一个频道,并在500毫秒后向该频道发送一条消息。现在让我们考虑您的代码:
case <-boom:
fmt.Println("BOOM!")
c, ok := <-boom
fmt.Println(c)
fmt.Println(ok)
它接收消息,打印boom,然后返回(结束程序)。如果你想让你的代码到达它输出“finnished”的位置,那么你需要下面的代码。请注意,需要标签循环
:
终止最里面的“for”、“switch”或“select”的执行
因此,如果没有标签中断,将退出select,但for循环将继续
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
loop:
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
break loop
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
fmt.Println("Finished")
}
主程序包
进口(
“fmt”
“时间”
)
func main(){
滴答声:=时间滴答声(100*时间毫秒)
动臂:=时间后(500*时间毫秒)
循环:
为了{
挑选{
casec
和ok
从不打印,因为从来没有通过boom
频道发送过任何其他内容。这是非常直接的。你是否有其他想法?如果你想重用它,你必须使用它。@Flimzy但在这种情况下不会永远收到block?程序如何终止?我不理解你的问题。正如我所说的是的,你的接收永远被阻塞,因为没有任何东西被发送。让我困惑的是程序确实终止了。或者至少当我在围棋场运行它时它终止了(你可以复制/粘贴我的代码并自己尝试一下?)。据我所知,它不应该终止,这就是为什么我对它退出围棋场感到困惑的原因“程序已退出:进程花费的时间太长。”。这是因为go Playway在沙箱中运行应用程序,这限制了执行时间(除其他外)。如果没有此选项,则有人将使用它来挖掘比特币:-)。尝试在您的计算机上运行它,它将不会退出。真的吗?对我来说,它在go Playder中退出时不会出现任何错误:/I在运行时,我将您的代码复制/粘贴到Playder中,这会导致“程序退出:进程耗时太长”
package main
import (
"fmt"
"time"
)
func main() {
tick := time.Tick(100 * time.Millisecond)
boom := time.After(500 * time.Millisecond)
loop:
for {
select {
case <-tick:
fmt.Println("tick.")
case <-boom:
fmt.Println("BOOM!")
break loop
default:
fmt.Println(" .")
time.Sleep(50 * time.Millisecond)
}
}
fmt.Println("Finished")
}