| // gen sends the values in nums on the returned channel, then closes it. |
| func gen(nums ...int) <-chan int { |
| // sq receives values from in, squares them, and sends them on the returned |
| // channel, until in is closed. Then sq closes the returned channel. |
| func sq(in <-chan int) <-chan int { |
| // merge receives values from each input channel and sends them on the returned |
| // channel. merge closes the returned channel after all the input values have |
| func merge(cs ...<-chan int) <-chan int { |
| var wg sync.WaitGroup // HL |
| // Start an output goroutine for each input channel in cs. output |
| // copies values from c to out until c is closed, then calls wg.Done. |
| output := func(c <-chan int) { |
| // Start a goroutine to close out once all the output goroutines are |
| // done. This must start after the wg.Add call. |
| // Distribute the sq work across two goroutines that both read from in. |
| // Consume the merged output from c1 and c2. |
| for n := range merge(c1, c2) { |
| fmt.Println(n) // 4 then 9, or 9 then 4 |