无法从通道获取值

我向通道插入一些值。之后我尝试将其从通道中取出,但它没有取出任何值并退出。有人知道为什么吗?


package main

import (

    "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 :  A

input :  B

input :  C

output : A

output : B

output : C

电流输出


input :  A

input :  B

input :  C


慕盖茨4494581
浏览 94回答 2
2回答

大话西游666

在将值添加到通道中之前,您的通道可能已关闭(close在 goroutine 的第一行之前调用)。那么频道里当然就没有什么可读的了。您可以切换到缓冲通道,而不是使用 goroutine 在通道中添加值,如下所示:package mainimport (&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; inputs := []string{"A", "B", "C"}&nbsp; &nbsp; c := make(chan string, len(inputs))&nbsp; &nbsp; for _, s := range inputs {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println( "input : ", s)&nbsp; &nbsp; &nbsp; &nbsp; c <- s&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; close(c)&nbsp; &nbsp; // recive&nbsp; &nbsp; for i := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("output", i)&nbsp; &nbsp; }}或者您可以使用 WaitGroup,如下所示:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")func main() {&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; inputs := []string{"A", "B", "C"}&nbsp; &nbsp; c := make(chan string)&nbsp; &nbsp; for _, s := range inputs {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println( "input : ", s)&nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; go func(s string) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c <- s&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; }(s)&nbsp; &nbsp; }&nbsp; &nbsp; go func(){&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(c)&nbsp; &nbsp; }()&nbsp; &nbsp; // recive&nbsp; &nbsp; for i := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("output", i)&nbsp; &nbsp; }}

红糖糍粑

您的代码中有几件事需要注意。第一个是s在闭包中使用 for 循环中的变量。go func() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c <- s&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }()在这里,您可能会得到不一致的值,因为您不知道这些 goroutine 何时执行。据您所知,您最终可能会向通道写入三次“C”。如果你想将它与单独的 goroutine 一起使用,请像这样使用它:go func(str string) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; c <- str&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }(s)对于未从通道检索的值,通道会在从中检索任何内容之前关闭。你可以这样写:package mainimport (&nbsp; &nbsp; "fmt")func main() {&nbsp; &nbsp; c := make( chan string)&nbsp; &nbsp; go func(){&nbsp; &nbsp; &nbsp; for _, s := range []string{"A", "B", "C"} {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println( "input : ", s)&nbsp; &nbsp; &nbsp; &nbsp; c <- s&nbsp;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; close( c)&nbsp; &nbsp; }()&nbsp; &nbsp; // recive&nbsp; &nbsp; for i := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("output", i)&nbsp; &nbsp; }}但即使这样也会给你这样的输出(甚至可能会有所不同):input :&nbsp; Ainput :&nbsp; Boutput Aoutput Binput :&nbsp; Coutput C为了获得您想要的输出,您可能需要使用缓冲通道和某种机制来防止读取,直到所有内容都写入通道。也许是这样的:package mainimport (&nbsp; &nbsp; "fmt"&nbsp; &nbsp; "sync")func main() {&nbsp; &nbsp; c := make( chan string,3)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; wg.Add(3)&nbsp; &nbsp; for _, s := range []string{"A", "B", "C"} {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println( "input : ", s)&nbsp; &nbsp; &nbsp; &nbsp; c <- s&nbsp;&nbsp; &nbsp; }&nbsp; &nbsp; go func(w *sync.WaitGroup){&nbsp; &nbsp; &nbsp; // recive&nbsp; &nbsp; &nbsp; for i := range c {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("output", i)&nbsp; &nbsp; &nbsp; &nbsp; w.Done()&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }(&wg)&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(c)}
打开App,查看更多内容
随时随地看视频慕课网APP