gpt4 book ai didi

go - 为什么从来没有到达返回声明

转载 作者:IT王子 更新时间:2023-10-29 01:36:44 26 4
gpt4 key购买 nike

看下面的代码片段

package main

import (
"fmt"
"time"
)

func sender(ch chan string) {

ch <- "Hello"
ch <- "Foo"
ch <- "and"
ch <- "Boo"
close(ch)
}

func main() {

ch := make(chan string)

go sender(ch)

for {
select {
case value := <-ch:
fmt.Println(value)
case <-time.After(time.Second * 2):
fmt.Println("Return")
return
}
}
}

结果我得到了空白输出和 time.After 将永远不会到达。为什么?

我注意到,当我尝试从关闭的 channel 接收值时,它将从该类型接收零值。为什么我仍然可以从封闭的 channel 中获得值(value)?

我也可以检查一下,

v, ok := <-ch

如果 ok 为 false,则 channel 关闭。

最佳答案

for 循环的每次迭代都会创建一个新的两秒计时器。关闭的 channel 随时准备接收。代码永远循环,因为在关闭的 channel 准备好接收之前,新计时器的 channel 永远不会准备好接收。

解决该问题的一种方法是将 channel 设置为 nil:

    case value, ok := <-ch:
if !ok {
ch = nil
} else {
fmt.Println(value)
}

在 nil channel 上接收永远不会就绪。

playground example

如果您希望循环最多运行两秒,那么您应该在循环外创建计时器:

    after := time.After(time.Second * 2)

并在循环中选择这个定时器:

    case <-after:
fmt.Println("Return")
return

playground example (添加 sleep 以使示例在 Playground 上运行)

您可以结合将 channel 设置为 nil 和在循环外创建计时器。

playground example

关于go - 为什么从来没有到达返回声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27978799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com