【发布时间】:2016-04-28 03:06:49
【问题描述】:
我正在处理 tour.golang.org 上的示例,但遇到了我不太理解的代码:
package main
import "fmt"
func fibonacci(c, quit chan int) {
x, y := 0, 1
for {
select {
case c <- x: // case: send x to channel c?
x, y = y, x+y
case <-quit: // case: receive from channel quit?
fmt.Println("quit")
return
}
}
}
func main() {
c := make(chan int)
quit := make(chan int)
go func() { // when does this get called?
for i := 0; i < 10; i++ {
fmt.Println(<-c)
}
quit <- 0
}()
fibonacci(c, quit)
}
我了解渠道如何工作的基础知识,但我不明白上述 select 语句的工作原理。教程上的解释说:
“select 语句让 goroutine 等待多个通信操作。 一个 select 阻塞,直到它的一个 case 可以运行,然后它执行那个 case。如果多个都准备好了,它会随机选择一个。”
但是案件是如何被执行的呢?据我所知,他们在说:
案例:将 x 发送到通道 c
案例:从退出接收
我想我明白第二个只有在 quit 有值时才会执行,这稍后会在 go func() 中完成。但是第一个案例检查的是什么?另外,在 go func() 内部,我们显然是在打印 c 的值,但是 c 中不应该有任何东西吗?我能想到的唯一解释是 go func() 在调用 fibonacci() 之后以某种方式执行。我猜这是一个我也不完全理解的 goroutine,它看起来就像魔法一样。
如果有人可以通过此代码并告诉我它在做什么,我将不胜感激。
【问题讨论】:
-
您关于“go func() // 何时调用此函数的问题?” --- 它在那里被调用 - 注意最后的 ()。这是一个内联函数/闭包,“go”异步运行它。两个线程互相交谈。它在后台运行 - 它从 c 读取(斐波那契正在写入的),一旦它读取了 10 个项目,它就会写入退出 - 告诉斐波那契它已经完成并且可以退出。内联块等待 c 上的数据。然后通过调用完成工作的 fibonacci() 继续执行。您可能会阅读本文并浏览其他文章。 blog.golang.org/pipelines
标签: go switch-statement channel