A nil channel disables a select case. After receiving the closed-channel flag, assign nil to that channel variable so selection continues across the remaining open channels. Without this step, a case for a closed channel remains continuously selectable. section 8.1.6
Accounting from sales and expenses
Read sales and expenses through one select loop. Add sales, subtract expenses, and set each channel to nil when it closes. Continue while either channel is non-nil; when both become nil, print the end-of-day balance. section 8.1.6
Listing 8.12 A main() goroutine using the nil select pattern
func main() { sales := generateAmounts(50) #1 expenses := generateAmounts(40) #2 endOfDayAmount := 0 for sales != nil || expenses != nil { #3 select { case sale, moreData := <-sales: #4 if moreData { fmt.Println("Sale of:", sale) endOfDayAmount += sale #5 } else { sales = nil #6 } case expense, moreData := <-expenses: #7 if moreData { fmt.Println("Expense of:", expense) endOfDayAmount -= expense #8 } else { expenses = nil #9 } } } fmt.Println("End of day profit and loss:", endOfDayAmount) } #1 Generates 50 amounts on the sales channel #2 Generates 40 amounts on the expenses channel #3 Continues to loop while there is a non-nil channel #4 Consumes the next amount and channel open flag from the sales channel\ #5 Adds the sales amount to the total end-of-day balance #6 If the channel has been closed, marks the channel as nil, disabling this select case #7 Consumes the next amount and channel open flag from the expenses channel #8 Subtracts the expense amount from the total end-of-day balance #9 If the channel has been closed, marks the channel as nil, disabling this select case
Inspect the complete Go listing for merging two generated amount streams with the nil select pattern. section 8.1.6
