Maison >développement back-end >Golang >Pourquoi la copie à partir d'une tranche Go entraîne-t-elle la réutilisation des adresses mémoire et comment y remédier ?

Pourquoi la copie à partir d'une tranche Go entraîne-t-elle la réutilisation des adresses mémoire et comment y remédier ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-25 21:34:11394parcourir

Why Does Copying from a Go Slice Result in Memory Address Reuse, and How Can It Be Fixed?

Réutilisation des adresses mémoire lors de la copie à partir de Golang Slice

Un malentendu courant dans la programmation Go concerne la copie d'adresses mémoire à partir de tranches. Considérez la situation suivante :

Vous disposez d'une interface Modèle et d'une structure Région qui l'implémente. L'interface est implémentée sur le pointeur de la structure Region. Vous disposez également d’une collection Regions, qui est une tranche d’objets Region. Vous disposez d'une méthode pour convertir un objet Regions en un []Model :

// Regions is the collection of the Region model
type Regions []Region

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, item := range *coll {
        output[idx] = &item
    }
    return output
}

Lorsque vous exécutez ce code, vous vous attendez à obtenir des adresses distinctes pour chaque modèle dans la tranche de sortie. Cependant, vous vous retrouvez avec le premier pointeur vers la région affiché plusieurs fois.

Pour résoudre ce problème, considérez l'élément de variable de boucle dans la méthode d'origine. C'est la même chose pour chaque itération de la boucle, donc la tranche résultante contient des références aux mêmes données sous-jacentes.

La solution de travail, en revanche, utilise i := (*coll)[idx] pour créer une nouvelle variable pour chaque itération. Cela garantit que chaque modèle dans la tranche de sortie possède une adresse mémoire unique.

Pour une meilleure compréhension, considérez l'extrait de code suivant :

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])
    }
}

Ce code démontre que l'adresse mémoire de v reste la même tout au long de la boucle, tandis que l'adresse mémoire de coll[i] augmente à chaque itération. Ce comportement est dû au fait que v est la variable de boucle, qui reste constante, tandis que coll[i] est une nouvelle variable 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!

Déclaration:
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