亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么通道沒有接收到成為結構體的成員

為什么通道沒有接收到成為結構體的成員

Go
ibeautiful 2023-07-17 16:54:58
代碼: https: //play.golang.org/p/Oh3oTa7GIPXtype a struct {    c chan bool}func (a *a) do() {    a.c <- true}type b struct {    c chan bool    a a}func main() {    b := b{        c: make(chan bool),        a: a{c: make(chan bool)},    }    go b.s()    b.c <- true    // below is to stay main gorutine alive    done := make(chan bool)    go func() {        time.Sleep(10 * time.Second)        done <- true    }()    for {        select {        case <-done:            fmt.Println("Done!")            return        }    }}func (b *b) s() {    for {        select {        case <-b.c:            fmt.Println("b c")            b.a.do()        case <-b.a.c:            fmt.Println("b a c")        }    }}上述實際輸出是b cDone!預期輸出:b cb a cDone !我不明白為什么它不打印b a c?代碼是不言自明的,如果還需要更多詳細信息,請詢問
查看完整描述

1 回答

?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

你的maingoroutine 在 上發送一個值b.c,然后等待:


b.c <- true

從 main 啟動的 goroutine:


go b.s()

這是從 接收的b.c,也是從 接收的b.a.c:


func (b *b) s() {

    for {

        select {

        case <-b.c:

            fmt.Println("b c")

            b.a.do()


        case <-b.a.c:

            fmt.Println("b a c")

        }

    }

}

如果從 接收到一個值b.c,則該 goroutine 會嘗試發送b.a.c(在a.do()方法中),并且您希望同一個goroutine 從 接收b.a.c。但由于b.a.c是無緩沖的,發送將被阻塞,因此它永遠不會到達b.s()它可以/將從中接收的下一個迭代b.a.c。


如果一個通道是無緩沖的,那么只有當有另一個 goroutine 準備從它接收數據時,才可以在該通道上進行發送。


如果您對b.a.c通道進行緩沖,則可以在不阻塞的情況下繼續發送,因此在下一次迭代中可以接收它:


a: a{c: make(chan bool, 1)}

通過此更改,您將獲得預期的輸出。在Go Playground上嘗試一下。



查看完整回答
反對 回復 2023-07-17
  • 1 回答
  • 0 關注
  • 145 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號