2 回答
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)
}
}
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)
}
- 2 回答
- 0 关注
- 127 浏览
添加回答
举报