Heim >Backend-Entwicklung >Golang >Wie implementiert man rekursive Generatoren in Go mithilfe von Kanälen idiomatisch?

Wie implementiert man rekursive Generatoren in Go mithilfe von Kanälen idiomatisch?

Susan Sarandon
Susan SarandonOriginal
2024-12-05 09:09:13864Durchsuche

How to Idiomatically Implement Recursive Generators in Go Using Channels?

Idiomatische Implementierung von Generatoren in Go für rekursive Funktionen

Der bereitgestellte Code demonstriert eine rekursive Generatorfunktion, die Kanäle verwendet, um einen Ertrag im Python-Stil zu simulieren.

Idiomatisch Implementierung

Idiomatisch können Generatoren in Go mithilfe von Goroutinen und Kanälen implementiert werden wie folgt:

  • Verwenden Sie eine anonyme Funktion, um den Generator als Goroutine zu starten: Dies ermöglicht eine ordnungsgemäße Handhabung des Schließens des Kanals und der Reaktion auf Signale vom Verbraucher.
  • Lassen Sie den Generator das Schließen des Kanals verzögern: Dadurch wird sichergestellt, dass der Kanal immer geschlossen ist, auch wenn der Generator ausgeschaltet ist Panik.
  • Erwägen Sie die Verwendung eines Signalkanals: Dies ermöglicht es dem Verbraucher, mit dem Generator zu kommunizieren, z. B. um eine Abtreibung zu beantragen.

Verantwortung für das Schließen des Kanals

Idiomatisch sollte die Generatorfunktion für das Schließen des Kanals verantwortlich sein. Dadurch wird sichergestellt, dass der Kanal geschlossen wird, wenn der Generator alle Werte gesendet hat.

Modifizierter Code

Der modifizierte Code kann idiomatisch geschrieben werden als folgt:

Bibliothek

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
}

Anrufer

func main() {
    channel := lib.PermutateWithChannel(fruits)
    for myFruits := range channel {
        fmt.Println(myFruits)
        if myFruits[0] == banned {
            return
        }
    }
}

Goroutine-Beendigung und Panik

Das Schließen des Kanals, nachdem der Verbraucher ihn geschlossen hat, führt nicht zu einer Panik. Tatsächlich führt der Versuch, einen Wert an einen geschlossenen Kanal zu senden, zu einem Fehler beim geschlossenen Kanal.

Nur-Empfangs-Kanäle

Um die Bibliotheksfunktion auf nur Empfangen zu beschränken, ist der idiomatische Ansatz besteht darin, einen separaten Kanaltyp für den Empfang von Werten und das Senden von Signalen zu verwenden. In diesem Fall hätte die Bibliotheksfunktion die folgende Signatur:

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

Das obige ist der detaillierte Inhalt vonWie implementiert man rekursive Generatoren in Go mithilfe von Kanälen idiomatisch?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn