求教一段 Go 代码

2017-11-29 12:10:36 +08:00
 dushandz
package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 1, 1
    for {
        select { //走到这里会阻塞等待
        case c <- x: //有数据传入通道 才会来 不是吗??
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c) //阻塞 直到有数据可以取才执行
        }
        quit <- 0
    }()
    fibonacci(c, quit)

}

通篇没有看到 向通道里传递值呀···· 怎么会走到 select 下的 case c <- x: 中去呢??

1895 次点击
所在节点    Go 编程语言
9 条回复
zhujinliang
2017-11-29 12:17:07 +08:00
c <- x 就是向 c 里传递值,那个 select 选择的是:要么 c 可写入,要么 quit 可读出。
hdczsf
2017-11-29 12:18:09 +08:00
package main

import "fmt"

func fibonacci(c, quit chan int) {
x, y := 1, 1
for {
select { //走到这里会阻塞等待
case c <- x: //① 这里把 x 传入通道 c,传入之后,②处立刻可以输出
x, y = y, x+y
case <-quit:
fmt.Println("quit")
return
}
}
}

func main() {
c := make(chan int)
quit := make(chan int)
go func() {
for i := 0; i < 10; i++ {
fmt.Println(<-c) //② 阻塞 直到有数据可以取才执行 ①处把 x 传入通道 c,这里立刻可以输出
}
quit <- 0
}()
fibonacci(c, quit)

}
araraloren
2017-11-29 13:25:33 +08:00
c,quit 都是 chan 的话,我一个没学过 go 的人都知道这操作明显是不同的
HarrisonZ
2017-11-29 14:07:05 +08:00
case c <- x 这是向 c 传值,只要 c 是可写的就会走到这里
dushandz
2017-11-29 14:54:42 +08:00
@hdczsf = =b 哦 好像明白了 那 select 的执行时随机的 保不齐走到 <- quit 发现 为 false ?
dushandz
2017-11-29 15:07:56 +08:00
@hdczsf 不好意思 没说明白 我又整理了下思路 是不是这样
② 阻塞 阻塞了 新开的 goroutine
fibonacci 里的 select 阻塞了 原来的 goroutine
然后发现两个 goroutine 都准备好了
随机执行了 case 语句 case <-quit: 执行返回 false ? 因为通道里没有数据? case c <- x: 返回了 true
dushandz
2017-11-29 15:09:37 +08:00
@hdczsf sorry select 监听到了 channel c 中有接收 所以会运行
picone
2017-11-29 18:26:51 +08:00
@dushandz #6
select 中 case 的发生是随机的,但是得有东西在 quit 中才可以执行到<- quit 啊。

chan 操作里面 chan <-是塞东西进 chan,没有缓冲或塞满会阻塞。
<- chan 操作是取出东西, 如果没东西出来的话会阻塞。
在 select 里面, 会随机执行一个非阻塞的 case
ehlxr
2018-01-10 13:27:46 +08:00
@HarrisonZ 正解

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/410442

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX