Maison > développement back-end > Golang > Comment implémenter de manière idiomatique des générateurs récursifs dans Go à l'aide de canaux ?

Comment implémenter de manière idiomatique des générateurs récursifs dans Go à l'aide de canaux ?

Susan Sarandon
Libérer: 2024-12-05 09:09:13
original
863 Les gens l'ont consulté

How to Idiomatically Implement Recursive Generators in Go Using Channels?

Implémentation idiomatique de générateurs dans Go pour les fonctions récursives

Le code fourni démontre une fonction de générateur récursif utilisant des canaux pour simuler le rendement de style Python.

Idiomatique Implémentation

Idiomatiquement, les générateurs dans Go peuvent être implémentés à l'aide de goroutines et de canaux comme suit :

  • Utilisez une fonction anonyme pour démarrer le générateur en tant que goroutine : Cela permet une gestion appropriée de la fermeture du canal et de la réponse aux signaux du consommateur.
  • Demander au générateur de différer la fermeture du canal : Cela garantit que le canal est toujours fermé, même si le générateur paniques.
  • Envisagez d'utiliser un canal de signal : Cela permet au consommateur de communiquer avec le générateur, par exemple pour demander un avortement.

Responsabilité de la fermeture du canal

Idiomatiquement, la fonction générateur devrait être responsable de la fermeture du canal. Cela garantit que le canal est fermé lorsque le générateur a fini d'envoyer toutes les valeurs.

Code modifié

Le code modifié peut être écrit idiomatiquement comme suit :

Bibliothèque

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
}
Copier après la connexion

Appelant

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

Résiliation de Goroutine et panique

Fermer le canal après que le consommateur l'a fermé ne provoquera pas de panique. En fait, essayer d'envoyer une valeur à un canal fermé entraînera une erreur de canal fermé.

Canaux de réception uniquement

Pour restreindre la fonction de bibliothèque à la réception uniquement, l'approche idiomatique consiste à utiliser un type de canal distinct pour recevoir des valeurs et envoyer des signaux. Dans ce cas, la fonction bibliothèque aurait la signature suivante :

func PermutateWithChannel(strings []string) (<-chan []string, chan<- struct{})
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal