Ihr Code sendet string
s auf dem Kanal richtig:
func doStuff(s string, ch chan string){
ch <- s
}
Das Problem ist auf der Empfängerseite:
results := <- c
fmt.Println("channel size = ", len(results))
// print the items in channel
for _,r := range results {
fmt.Println(string(r))
}
results
ist ein einzelner Wert, der vom Kanal empfangen wird (der erste Wert, der darauf gesendet wird). Und Sie drucken die Länge dieser string
.
Dann Schleife über diese Zeichenfolge (results
) mit einer for range
, die über seine rune
s Schleifen, und Sie drucken diese.
Was Sie wollen, ist eine Schleife über den Werten des Kanals:
// print the items in channel
for s := range c {
fmt.Println(s)
}
Das bei der Ausführung in einer Laufzeit Panik führen:
fatal error: all goroutines are asleep - deadlock!
Weil Sie nie den Kanal schließen, und ein for range
auf einem Kanal läuft, bis der Kanal geschlossen ist. Also musst du den Kanal irgendwann schließen.
Zum Beispiel lassen Sie uns 1 Sekunde warten, schließen Sie es dann:
go func() {
time.Sleep(time.Second)
close(c)
}()
Auf diese Weise Ihre App wird nach 1 Sekunde ausführen und beenden. Versuchen Sie es auf der Go Playground.
Eine andere, schönere Lösung ist sync.WaitGroup
zu verwenden: Dies wartet, bis alle goroutines fertig sind (Senden eines Wertes auf dem Kanal), dann schließt es den Kanal (es gibt also keine unnötige Wartezeit/Verzögerung).
var wg = sync.WaitGroup{}
func doStuff(s string, ch chan string) {
ch <- s
wg.Done()
}
// And in main():
for i := 0; i < len(loops); i++ {
wg.Add(1)
go doStuff("helloooo", c)
}
go func() {
wg.Wait()
close(c)
}()
Versuchen Sie dieses auf dem Go Playground.
Hinweise:
etwas 5-mal zu wiederholen, brauchen Sie nicht, dass hässliche loops
Array.Einfach tun:
for i := 0; i < 5; i++ {
// Do something
}
Vielen Dank für die detaillierte Information. – Sudhakar