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

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

無法從通道獲取值

無法從通道獲取值

Go
慕蓋茨4494581 2023-07-31 15:02:14
我向通道插入一些值。之后我嘗試將其從通道中取出,但它沒有取出任何值并退出。有人知道為什么嗎?package mainimport (    "fmt")func main() {    c := make( chan string)    for _, s := range []string{"A", "B", "C"} {        fmt.Println( "input : ", s)        go func() {            c <- s         }()    }    close( c)    // recive    for i := range c {        fmt.Println("output", i)    }}期望輸出input :  Ainput :  Binput :  Coutput : Aoutput : Boutput : C電流輸出input :  Ainput :  Binput :  C
查看完整描述

2 回答

?
大話西游666

TA貢獻1817條經驗 獲得超14個贊

在將值添加到通道中之前,您的通道可能已關閉(close在 goroutine 的第一行之前調用)。那么頻道里當然就沒有什么可讀的了。您可以切換到緩沖通道,而不是使用 goroutine 在通道中添加值,如下所示:


package main

import (

    "fmt"

)

func main() {

    inputs := []string{"A", "B", "C"}

    c := make(chan string, len(inputs))

    for _, s := range inputs {

        fmt.Println( "input : ", s)

        c <- s 

    }

    close(c)

    // recive

    for i := range c {

        fmt.Println("output", i)

    }

}

或者您可以使用 WaitGroup,如下所示:


package main

import (

    "fmt"

    "sync"

)

func main() {

    var wg sync.WaitGroup

    inputs := []string{"A", "B", "C"}

    c := make(chan string)

    for _, s := range inputs {

        fmt.Println( "input : ", s)

        wg.Add(1)

        go func(s string) {

            c <- s

            wg.Done()

        }(s)

    }

    go func(){

        wg.Wait()

        close(c)

    }()


    // recive

    for i := range c {

        fmt.Println("output", i)

    }

}


查看完整回答
反對 回復 2023-07-31
?
紅糖糍粑

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

您的代碼中有幾件事需要注意。


第一個是s在閉包中使用 for 循環中的變量。


go func() {

            c <- s 

        }()

在這里,您可能會得到不一致的值,因為您不知道這些 goroutine 何時執行。據您所知,您最終可能會向通道寫入三次“C”。如果你想將它與單獨的 goroutine 一起使用,請像這樣使用它:


go func(str string) {

                c <- str 

            }(s)

對于未從通道檢索的值,通道會在從中檢索任何內容之前關閉。你可以這樣寫:


package main

import (

    "fmt"

)

func main() {

    c := make( chan string)

    go func(){

      for _, s := range []string{"A", "B", "C"} {

        fmt.Println( "input : ", s)

        c <- s 

      }

      close( c)

    }()

    // recive

    for i := range c {

        fmt.Println("output", i)

    }

}

但即使這樣也會給你這樣的輸出(甚至可能會有所不同):


input :  A

input :  B

output A

output B

input :  C

output C

為了獲得您想要的輸出,您可能需要使用緩沖通道和某種機制來防止讀取,直到所有內容都寫入通道。也許是這樣的:


package main

import (

    "fmt"

    "sync"

)

func main() {

    c := make( chan string,3)

    var wg sync.WaitGroup

    wg.Add(3)

    for _, s := range []string{"A", "B", "C"} {

        fmt.Println( "input : ", s)

        c <- s 

    }



    go func(w *sync.WaitGroup){

      // recive

      for i := range c {

        fmt.Println("output", i)

        w.Done()

      }

    }(&wg)


    wg.Wait()

    close(c)

}


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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