Maison >développement back-end >Golang >Pourquoi la copie à partir d'une tranche Go avec une boucle de plage duplique-t-elle parfois les adresses mémoire ?

Pourquoi la copie à partir d'une tranche Go avec une boucle de plage duplique-t-elle parfois les adresses mémoire ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-23 19:17:15951parcourir

Why Does Copying from a Go Slice with a Range Loop Sometimes Duplicate Memory Addresses?

Réutilisation de l'adresse mémoire lors de la copie depuis une tranche dans Go

Vous avez rencontré un comportement particulier dans Go où la copie des valeurs d'une tranche à l'aide d'une plage La boucle entraînait des adresses mémoire dupliquées dans la sortie. Pour résoudre ce problème, vous avez modifié le code pour créer une variable temporaire, qui a produit les adresses distinctes attendues.

Ce comportement se produit car dans le code d'origine, l'élément de variable de boucle est un pointeur vers l'élément actuel de la tranche. . Au fur et à mesure que vous parcourez la tranche, Go réutilise cette variable de pointeur, en changeant sa valeur à chaque itération mais en conservant la même adresse mémoire. Par conséquent, lorsque vous attribuez &item à la tranche de sortie, vous dupliquez par inadvertance plusieurs fois la même adresse mémoire.

Pour empêcher cette réutilisation, votre code modifié crée une variable temporaire i pour contenir une copie de l'élément actuel. Cela oblige Go à créer une nouvelle allocation de mémoire pour chaque itération, ce qui entraîne des adresses uniques dans la tranche de sortie.

Pour illustrer ce concept, considérons l'exemple suivant :

package main

import "fmt"

type Region struct {
    Name string
}

func main() {
    // Create a slice of Region objects.
    regions := []Region{
        {Name: "Central"},
        {Name: "East"},
    }

    // Original code - duplicates memory addresses
    fmt.Println("Original Code:")
    models1 := make([]Model, len(regions))
    for idx, item := range regions {
        models1[idx] = &item
    }
    for _, m := range models1 {
        fmt.Println(m)
    }

    // Modified code - generates unique memory addresses
    fmt.Println("Modified Code:")
    models2 := make([]Model, len(regions))
    for idx, _ := range regions {
        i := regions[idx]
        models2[idx] = &i
    }
    for _, m := range models2 {
        fmt.Println(m)
    }
}

Exécuter ce code , vous remarquerez que le code original imprime les adresses mémoire dupliquées, tandis que le code modifié produit des adresses uniques.

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