Un problème curieux est survenu dans un projet impliquant des pointeurs Go. Le problème était que lors de la conversion d'une tranche d'objets struct en une tranche d'interfaces, l'adresse mémoire du premier pointeur était utilisée à plusieurs reprises dans la sortie.
Pour résoudre ce problème, le développeur a modifié la fonction de conversion pour utiliser un extra variable, qui a donné le résultat attendu.
Cela soulève la question : pourquoi la solution originale a-t-elle échoué ? Pour comprendre cela, nous devons examiner comment Go gère les pointeurs et les tranches.
Dans Go, l'expression *coll renvoie un en-tête de tranche contenant des informations sur le tableau sous-jacent, sa longueur et sa capacité. Lors de l'accès à un élément d'une tranche, l'expression (*coll)[idx] est utilisée, qui renvoie une référence à l'élément à l'index idx.
Dans la solution originale, item était la variable de boucle dans la plage *boucle de collage. Cette boucle parcourt l'en-tête de la tranche, attribuant chaque élément de la tranche à l'élément variable de boucle. Cependant, puisque item est la variable de la boucle, son adresse mémoire reste la même tout au long de la boucle. Par conséquent, lorsque &item est ajouté à la tranche de sortie, la même adresse mémoire est ajoutée plusieurs fois, ce qui entraîne le comportement observé.
La solution révisée utilise l'expression i := (*coll)[idx] dans le boucle pour affecter l’élément à l’index idx à une variable locale i. Cette variable a une adresse mémoire distincte de l'élément de variable de boucle, et ainsi, lorsque &i est ajouté à la tranche de sortie, chaque élément a une adresse mémoire différente.
Pour illustrer la différence d'adresses mémoire entre la variable de boucle et l'élément auquel vous accédez, considérez le code suivant :
package main import "fmt" func main() { coll := []int{5, 10, 15} for i, v := range coll { fmt.Printf("This one is always the same; %v\n", &v) fmt.Println("This one is 4 bytes larger each iteration; %v\n", &coll[i]) } }
L'exécution de ce code démontrera que &v a la même adresse mémoire pour toutes les itérations de la boucle, tandis que &coll[i] a une mémoire différente adresse pour chaque itération.
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!