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 關注
- 167 瀏覽
添加回答
舉報