Home >Backend Development >Golang >How to Idiomatically Implement Recursive Generators in Go Using Channels?
The provided code demonstrates a recursive generator function using channels to simulate Python-style yield.
Idiomatically, generators in Go can be implemented using goroutines and channels as follows:
Idiomatically, the generator function should be responsible for closing the channel. This ensures that the channel is closed when the generator finishes sending all the values.
The modified code can be written idiomatically as follows:
Library
func permutateWithChannel(channel chan<- []string, strings, prefix []string) { defer close(channel) length := len(strings) if length == 0 { channel <- prefix return } newStrings := make([]string, 0, length-1) for i, s := range strings { newStringsI := append(newStrings, strings[:i]...) newStringsI = append(newStringsI, strings[i+1:]...) newPrefixI := append(prefix, s) go permutateWithChannel(channel, newStringsI, newPrefixI) } } func PermutateWithChannel(strings []string) chan []string { channel := make(chan []string) prefix := make([]string, 0, len(strings)) go permutateWithChannel(channel, strings, prefix) return channel }
Caller
func main() { channel := lib.PermutateWithChannel(fruits) for myFruits := range channel { fmt.Println(myFruits) if myFruits[0] == banned { return } } }
Closing the channel after the consumer has closed it will not cause a panic. In fact, trying to send a value to a closed channel will result in a closed channel error.
To restrict the library function to be receive-only, the idiomatic approach is to use a separate channel type for receiving values and sending signals. In this case, the library function would have the following signature:
func PermutateWithChannel(strings []string) (<-chan []string, chan<- struct{})
The above is the detailed content of How to Idiomatically Implement Recursive Generators in Go Using Channels?. For more information, please follow other related articles on the PHP Chinese website!