Pendant le processus de développement, nous devons souvent utiliser le canal de Golang. Lorsque nous utilisons le canal pour terminer la tâche, nous devons fermer le canal à temps pour éviter le blocage, afin d'obtenir l'effet d'optimisation du programme.
Alors, dans quelles circonstances faut-il fermer la chaîne ? Comment fermer correctement la chaîne ? Dans Golang, la fermeture de chaîne est en effet un sujet relativement complexe. Explorons ce sujet ci-dessous.
1. Pourquoi devez-vous fermer la chaîne ?
Tout d'abord, il doit être clair que le canal ne doit pas être fermé. En d'autres termes, Golang fermera automatiquement le canal lorsque le dernier pointeur vers le canal sera détruit. Mais ne pas fermer le canal entraînera les problèmes suivants :
2. Comment fermer la chaîne correctement ?
Maintenant que nous savons pourquoi nous devons fermer la chaîne, comment fermer la chaîne correctement ? En fait, Golang propose deux façons de fermer la chaîne :
La manière la plus simple et la plus courante de fermer la chaîne est d'utiliser la fonction close() fournie par Golang. Le format de syntaxe de cette fonction est le suivant :
close(channel)
Cette fonction doit transmettre un paramètre de type de canal. Lorsque le paramètre de type de canal transmis est fermé, il ne peut plus être envoyé ou reçu, sinon une panique se produira.
La deuxième façon couramment utilisée pour fermer un canal consiste à utiliser une boucle for range. Cette méthode est plus courante pour les opérations qui reçoivent des valeurs du canal. Pour les opérations d'envoi de données vers un canal, cette méthode est rarement utilisée pour fermer le canal. L'exemple de code d'utilisation d'une boucle for range pour fermer un canal est le suivant :
for val := range channel { fmt.Println(val) } // channel被关闭后,上述代码会正常退出循环
Dans une boucle for range, lorsque le canal est fermé, la boucle se termine automatiquement. Il convient de noter que si nous utilisons des instructions telles que break ou continue dans la boucle for range pour sortir de la boucle, nous ne pouvons pas éviter la poursuite de l'opération de réception du canal.
3. Comment éviter la panique provoquée par la fermeture de la chaîne ?
Lorsque vous utilisez la fonction close() pour fermer un canal, un point important à noter est que nous devons nous assurer que le canal est fermé une fois toutes les opérations d'envoi de toutes les valeurs au canal terminées, sinon l'opération de fermeture pourrait être effectué avant que le canal ne soit entièrement accepté. Provoquera la panique. Voyons comment éviter que cela ne se produise.
Pour certains calculs complexes ou opérations de vérification qui doivent être effectués avant l'envoi de données, nous pouvons utiliser des canaux en cache pour éviter les situations de panique. L'implémentation spécifique est la suivante :
ch := make(chan bool, 1) go func() { // 进行复杂计算或者校验操作 // ... ch <- true }() select { case <- done: // 结束操作 case <- ch: // 处理收到的数据 } close(ch)
Dans le code ci-dessus, nous utilisons un canal avec un tampon de 1. Ce canal stocke uniquement une valeur booléenne lorsque nous terminons l'opération complexe après avoir créé la goroutine, nous envoyons une valeur vraie au canal pour indiquer que l'opération est terminée. Attendez ensuite dans l'instruction select pour envoyer des valeurs au canal ou recevoir des valeurs d'autres canaux. Enfin, nous fermons le canal en utilisant la fonction close().
Lors de l'utilisation de l'instruction select, nous pouvons utiliser la branche par défaut pour gérer le scénario avant la fermeture du canal. L'exemple de code est le suivant :
func handleCh(channel chan int) { for { select { case val, ok := <- channel: if !ok { fmt.Println("channel has closed") return } fmt.Println("recieve val:", val) default: fmt.Println("no value received") } } } func main() { ch := make(chan int) for i := 0; i < 5; i++ { go func(val int) { ch <- val }(i) } close(ch) handleCh(ch) } // 输出结果: // recieve val: 0 // recieve val: 1 // recieve val: 2 // recieve val: 3 // recieve val: 4 // channel has closed
Dans le code ci-dessus, nous avons créé une fonction handleCh() pour gérer la valeur reçue du canal. Dans cette fonction, nous utilisons l'instruction select pour traiter les données reçues du canal et gérer le scénario lorsque le canal n'est pas fermé dans la branche par défaut. Lorsque nous fermons le canal dans la fonction principale, la fonction handleCh() se terminera normalement. Cependant, il convient de noter que lors de l'utilisation de la branche par défaut, elle doit être placée à la fin, sinon cela provoquera des erreurs de programme.
4. Résumé
Grâce à l'introduction ci-dessus, nous comprenons les raisons et les méthodes de fermeture de chaîne dans Golang. De manière générale, nous devons fermer le canal manuellement pour éviter des problèmes tels que des fuites de mémoire et des blocages. Lors de la fermeture du canal, nous devons utiliser respectivement la fonction close() ou l'instruction de boucle for range pour éviter la panique. À l'heure actuelle, dans le développement réel, nous pouvons utiliser des canaux mis en cache ou sélectionner des instructions pour traiter la scène avant la fermeture du canal, afin d'atteindre l'objectif d'optimisation de l'effet du programme.
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!