Maison > développement back-end > Golang > Pourquoi la conversion directe de tranches dans Go réutilise-t-elle la même adresse mémoire pour les pointeurs ?

Pourquoi la conversion directe de tranches dans Go réutilise-t-elle la même adresse mémoire pour les pointeurs ?

Mary-Kate Olsen
Libérer: 2025-01-02 15:40:40
original
451 Les gens l'ont consulté

Why Does Direct Slice Conversion in Go Reuse the Same Memory Address for Pointers?

Go Slices et réutilisation de la mémoire

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

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!

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