提供されたコードは、チャネルを使用して Python スタイルの利回りをシミュレートする再帰ジェネレーター関数を示しています。
慣用的に、Go のジェネレーターは次のようにゴルーチンとチャネルを使用して実装できます:
慣用的に、ジェネレーター関数はチャネルを閉じる責任があります。これにより、ジェネレーターがすべての値の送信を終了したときにチャネルが確実に閉じられます。
変更されたコードは、慣用的に次のように記述できます。
ライブラリ
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 中国語 Web サイトの他の関連記事を参照してください。