Call différé dans une boucle for - existe-t-il un meilleur moyen de retarder la lecture de la réponse du canal ? Il s'agit d'un problème courant que de nombreux développeurs rencontrent lorsqu'ils utilisent le langage Go. Le mot-clé defer est utilisé pour retarder l'exécution des fonctions dans le langage Go. L'utilisation de defer dans une boucle for peut garantir que certaines opérations sont effectuées après la fin de chaque boucle. Cependant, si vous devez lire la réponse du canal à chaque boucle, l'utilisation du report n'est peut-être pas le meilleur choix. Alors, existe-t-il un meilleur moyen de retarder la lecture de la réponse du canal ? Explorons-le ensemble.
J'essaie d'appeler une fonction qui renvoie un canal en boucle. Ajoutez ensuite ce canal à la tranche channelslice
. Enfin, parcourez les tranches de canal et imprimez la réponse pour chaque canal. Lorsque je fais cela, mon IDE affiche l'avertissement :
possible resource leak, 'defer' is called in the 'for' loop
Comme vous pouvez le voir, j'appelle close(channelslice[i])
à l'intérieur de la seconde boucle for. N'est-ce pas recommandé ? De plus, comment cela pourrait-il provoquer une fuite de ressources ? Existe-t-il une meilleure façon de gérer la fermeture ou le découpage des canaux ?
package main import ( "fmt" "math/rand" ) func t() chan int { c := make(chan int) go func() { c <- rand.Intn(100) }() return c } func main() { channelSlice := make([]chan int, 0) for i := 0; i<100; i++ { // Keep making concurrent calls // Will read responses from the channel later channelSlice = append(channelSlice, t()) } for i := 0; i<100; i++ { defer close(channelSlice[i]) // Warning thrown by IDE fmt.Println(<-channelSlice[i]) } }
Comme @mkopriva l'a souligné,
Les appels retardés sont exécutés à la sortie des fonctions environnantes, ils ne sont pas appelés à la sortie des blocs non fonctionnels environnants. Encapsulez le corps de la boucle dans une fermeture.
Voici ce que j'ai fait :
for i := 0; i<100; i++ { func() { defer close(channelSlice[i]) fmt.Println(<-channelSlice[i]) }() }
Comme vous pouvez le voir, j'ai enveloppé l'instruction defer
dans un iife (expression de fonction immédiatement invoquée). Ce serait aussi bien d’en faire une fermeture.
Cela garantit que le canal sera désormais fermé et qu'aucune fuite de mémoire ne se produira.
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!