提供的代码演示了使用通道模拟 Python 风格的递归生成器函数。
按照惯例,Go 中的生成器可以使用以下方式实现goroutine 和通道如下:
通常,生成器函数应该负责关闭通道。这可以确保当生成器完成发送所有值时关闭通道。
修改后的代码可以惯用地编写为如下:
库
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 }
调用者
func main() { channel := lib.PermutateWithChannel(fruits) for myFruits := range channel { fmt.Println(myFruits) if myFruits[0] == banned { return } } }
消费者关闭通道后关闭通道不会引起恐慌。事实上,尝试向关闭的通道发送值将导致关闭通道错误。
将库函数限制为仅接收,惯用的方法是使用单独的通道类型来接收值和发送信号。在这种情况下,库函数将具有以下签名:
func PermutateWithChannel(strings []string) (<-chan []string, chan<- struct{})
以上是如何使用通道在 Go 中惯用地实现递归生成器?的详细内容。更多信息请关注PHP中文网其他相关文章!