Hi all,
I am trying try to learn channels and when I ran the code I get following output which uppercase after the first run. in playground I get all lowercase. running v1.10
thanks in advance
google
ALTAVISTA
ALPHABET
BING
YAHOO
func main() {
names := []string{
"yahoo", "google", "altavista", "alphabet", "bing",
}
n := make(chan string, len(names))
for _, name := range names {
n <- name
go ToUpper(n)
}
for i := 0; i < len(names); i++ {
fmt.Println(<-n)
}
close(n)
}
func ToUpper(c chan string) {
u := strings.ToUpper(<-c)
c <- u
}
You do not wait for goroutines to finish. Better play with unbuffered channels and use waitgroups. The simplest but not good solution would be to add some sleep at the end of main().
One more thing, use channels just to read or write, not both.
Use separate channels for the input and for the result.
In your code, the ToUpper goroutines and the fmt.Println loop in the main goroutine read from the same channel that contains both the input and the output of ToUpper(). There is no defined sequence in which the goroutines run, so the result is undetermined.
The playground runs the fmt.Println loop first, which is why you get the unprocessed input as output. When the ToUpper goroutines run, the channel is already empty. (Apart from that, when the main goroutine ends, all other goroutines are stopped immediately, so the ToUpper goroutines may never run.)
On your local machine, the fmt.Println() loop seems to run at least once before the first ToUpper goroutine starts, which is why you see the first ouput unprocessed.
Using separate channels for input and result values should fix the issue. And ensure to let the main goroutine wait for the other goroutines to finish. (See e.g. sync/WaitGroup.)