Back in August I wrote up a sample executing a function 50 times in parallel using goroutines and channels. In that example, the code was as follows:

packagemainimport"fmt"import"time"funcprocess(iint)string{time.Sleep(time.Duration(1)*time.Second)returnfmt.Sprintf("Job %d done",i)}funcmain(){jobCount:=50c:=make(chanstring)// Create 50 goroutinesfori:=1;i<=jobCount;i++{gofunc(iint){c<-process(i)// send the result of process(i) to the channel c}(i)}// Fetch the goroutine messages in the channel once they're done.fori:=1;i<=jobCount;i++{fmt.Println(<-c)// read the message from channel c}}

There's another way this could be written:

packagemainimport"fmt"import"time"funcprocess(iint,cchanstring){gofunc(iint,cchanstring){time.Sleep(time.Duration(1)*time.Second)c<-fmt.Sprintf("Job %d done",i)}(i,c)}funcmain(){jobCount:=50c:=make(chanstring)// Create 50 goroutinesfori:=1;i<=jobCount;i++{process(i,c)// send the result of process(i) to the channel c}// Fetch the goroutine messages in the channel once they're done.fori:=1;i<=jobCount;i++{fmt.Println(<-c)// read the message from channel c}}

You might notice I've moved the goroutine into the process() function, and I'm passing the channel itself as a parameter. This leaves us with the channel to be read from within the scope of main, but someone calling the process method doesn't need to explicitly declare the goroutine. Of course, this depends on the problem you're trying to solve, but this is another pattern you can use to remove the need for setup of the goroutine in the code calling your process() function, whatever it may be. It makes for a cleaner main() function.