为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 返回通道

Golang 返回通道

Go
拉丁的传说 2021-09-13 19:43:21
我正在尝试使用 Go 频道并与以下来自 go 博客的函数示例混淆:func gen(nums []int) <-chan int {    out := make(chan int)    go func() {        for _, n := range nums {            out <- n        }        close(out)    }()    fmt.Println("return statement is called ")    return out}主要的 :func main() {    c := make(chan int)    c = gen([]int{2, 3, 4, 5})    // Consume the output.    // Print 2,3,4,5    fmt.Println(<-c)    fmt.Println(<-c)    fmt.Println(<-c)    fmt.Println(<-c)}完整代码:http : //play.golang.org/p/Qh30wzo4m0我的疑问:我的理解是,一旦return被调用,该函数将被终止,并且该函数内的通道不再有生命力。该return语句只调用一次。但是out频道的内容被读取了很多次。在这种情况下,实际的执行流程是什么?(我是并发编程的新手。)
查看完整描述

3 回答

?
ibeautiful

TA贡献1993条经验 获得超5个赞

out := make(chan int)

这不是缓冲通道,这意味着out <- n阻塞,直到有人在某处读取该通道(fmt.Println(<-c)调用)
(另请参阅“ do golang 通道维护顺序”)

所以gen()函数末尾的返回并不意味着文字go func()被终止(因为它仍在等待读者消费out频道的内容)。

但是main函数获取out通道作为gen()函数的返回。终止
后如何获得它gen()

gen()终止的事实对其返回值(out通道)没有影响:“ gen()”的目标是“生成”该out通道。

main可以在终止后很长时间使用out(作为 的返回值gen()gen()

字面go funcgen()仍然运行,即使gen()被终止。


查看完整回答
反对 回复 2021-09-13
?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

因为gen()将通道填充函数作为 goroutine 触发;


go func() {

    for _, n := range nums {

        out <- n

    }

    close(out)

}()

并且当第一个值在out通道上发送时它会阻塞,因为还没有接收任何东西(无缓冲的通道在发送时阻塞,直到有东西在它们上接收),当gen()函数返回时,goroutine不会结束。


从收到c的main()


fmt.Println(<-c)

...

然后导致 goroutine 在gen()读取结果时继续填充通道,然后main()在 goroutine 返回时最终返回,因为没有什么可以发送了out,也没有什么可以接收了c。


此外,c := make(<-chan int)inmain()是不必要的,因为gen()创建了一个频道并返回它。


见游乐场


查看完整回答
反对 回复 2021-09-13
  • 3 回答
  • 0 关注
  • 185 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信