求教一段 Go 代码 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
dushandz
V2EX    Go 编程语言

求教一段 Go 代码

  •  
  •   dushandz 2017-11-29 12:10:36 +08:00 2323 次点击
    这是一个创建于 2946 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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: 中去呢??

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

    chan 操作里面 chan <-是塞东西进 chan,没有缓冲或塞满会阻塞。
    <- chan 操作是取出东西, 如果没东西出来的话会阻塞。
    在 select 里面, 会随机执行一个非阻塞的 case
    ehlxr
        9
    ehlxr  
       2018-01-10 13:27:46 +08:00
    @HarrisonZ 正解
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5405 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 27ms UTC 08:58 PVG 16:58 LAX 00:58 JFK 03:58
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86