ホームページ >バックエンド開発 >Golang >チャネルを使用して Go で再帰的ジェネレーターを慣用的に実装するにはどうすればよいですか?

チャネルを使用して Go で再帰的ジェネレーターを慣用的に実装するにはどうすればよいですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-12-05 09:09:13864ブラウズ

How to Idiomatically Implement Recursive Generators in Go Using Channels?

再帰関数用に Go でジェネレーターを慣用的に実装する

提供されたコードは、チャネルを使用して Python スタイルの利回りをシミュレートする再帰ジェネレーター関数を示しています。

慣用的実装

慣用的に、Go のジェネレーターは次のようにゴルーチンとチャネルを使用して実装できます:

  • 匿名関数を使用してジェネレーターをゴルーチンとして開始します: これチャネルを閉じたり、からの信号に応答したりする適切な処理が可能になります。 Consumer.
  • ジェネレーターにチャネルのクローズを延期させます: これにより、ジェネレーターがパニックになった場合でも、チャネルは常に閉じられます。
  • シグナルの使用を検討してください。 channel: これにより、コンシューマがジェネレータと通信できるようになります。たとえば、リクエストを行うことができます。

チャネルを閉じる責任

慣用的に、ジェネレーター関数はチャネルを閉じる責任があります。これにより、ジェネレーターがすべての値の送信を終了したときにチャネルが確実に閉じられます。

変更コード

変更されたコードは、慣用的に次のように記述できます。

ライブラリ

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
        }
    }
}

Goroutine の終了とパニック

コンシューマがチャネルを閉じた後にチャネルを閉じても、パニックは発生しません。実際、閉じられたチャネルに値を送信しようとすると、閉じられたチャネル エラーが発生します。

受信専用チャネル

ライブラリ関数を受信専用に制限するには、慣用的なアプローチを使用します。値の受信と信号の送信に別のチャネル タイプを使用することです。この場合、ライブラリ関数には次のシグネチャが含まれます:

func PermutateWithChannel(strings []string) (<-chan []string, chan<- struct{})

以上がチャネルを使用して Go で再帰的ジェネレーターを慣用的に実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。