Maison > développement back-end > Golang > Pourquoi l'ajout à une copie d'une tranche Go modifie-t-il également la tranche d'origine ?

Pourquoi l'ajout à une copie d'une tranche Go modifie-t-il également la tranche d'origine ?

Patricia Arquette
Libérer: 2024-11-20 14:53:14
original
635 Les gens l'ont consulté

Why does appending to a copy of a Go slice also modify the original slice?

Comprendre l'ajout de tranches et son effet sur la tranche d'origine

Lorsque vous travaillez avec des tranches dans Go, la fonction d'ajout est souvent utilisée pour ajouter de nouveaux éléments à une tranche existante. Cependant, de nombreux développeurs pourraient être surpris de découvrir que cette opération d'ajout peut également modifier la tranche d'origine.

Le code en cours d'examen

Considérez l'extrait de code suivant :

func someFunc(A []int) int {
    for i := 0; i < len(A); i++ {
        tempA := A // copy the slice by value

        fmt.Println("A: ", A)
        fmt.Println("tempA: ", A)
        fmt.Println()

        newArr = remove(tempA, i)

        if isAesthetic(newArr) {
            ways++
        }
    }
}

func remove(slice []int, s int) []int {
    return append(slice[:s], slice[s+1:]...)
}
Copier après la connexion

Ici, la fonction someFunc prend une tranche A en entrée puis crée une copie de A appelée tempA, avant d'appeler la fonction Remove pour supprimer un élément de tempA. En inspectant la fonction en action, vous remarquerez peut-être la sortie de console suivante :

A:  [3 4 5 3 7]
tempA:  [3 4 5 3 7]

A:  [4 5 3 7 7]
tempA:  [4 5 3 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]

A:  [4 3 7 7 7]
tempA:  [4 3 7 7 7]
Copier après la connexion

L'effet secondaire surprenant

Pendant l'exécution du code, il imprime le contenu de A et tempA, révélant que la tranche d'origine A est également modifiée après l'appel de l'ajout sur tempA. Ce comportement peut sembler contre-intuitif à première vue, car on pourrait s'attendre à ce qu'une copie par valeur de A soit indépendante de toute modification apportée à tempA.

Cependant, ce phénomène est une conséquence directe de la façon dont les tranches sont implémentées. en Aller. Les tranches sont essentiellement une structure de données légère composée d'un en-tête et d'un pointeur vers le tableau sous-jacent. L'en-tête comprend des informations sur la longueur et la capacité de la tranche, tandis que le pointeur pointe vers le premier élément de la tranche.

Lorsque vous attribuez la valeur de A à tempA, vous créez essentiellement un nouvel en-tête de tranche qui pointe vers le même tableau sous-jacent que A. Ainsi, toute modification apportée à tempA sera également reflétée dans A, car les deux tranches font référence aux mêmes données.

Comprendre les en-têtes et les tableaux de tranche

Pour mieux comprendre ce comportement, il est utile de comprendre comment les en-têtes de tranche et les tableaux interagissent dans Go. Un tableau contient un bloc contigu d’éléments du même type. Une tranche, quant à elle, fournit une vue dynamique d’une section du tableau. Il décrit un ensemble consécutif d'éléments dans le tableau, mais il ne possède pas les données du tableau sous-jacent.

Lorsque vous créez une tranche à partir d'un tableau en utilisant la syntaxe []T{e1, e2, ..., fr}, vous créez essentiellement un nouvel en-tête de tranche qui pointe vers le premier élément du tableau. La longueur de la tranche est définie sur n et la capacité est définie sur la longueur restante du tableau après la tranche.

De même, lorsque vous créez un en-tête de tranche en utilisant la syntaxe []T(arr), vous créez une tranche qui pointe vers le même tableau sous-jacent que arr. La longueur de la tranche est définie sur la longueur de l'arr et la capacité est définie sur la capacité de l'arr.

Implications et meilleures pratiques

Comprendre la relation entre les tranches et les tableaux peut vous aider à éviter les pièges potentiels et à écrire du code Go plus efficace. Lorsque vous travaillez avec des tranches, gardez à l'esprit les points suivants :

  • Évitez d'attribuer une tranche à une autre tranche si vous souhaitez conserver des références indépendantes au même tableau sous-jacent.
  • Utilisez copy(dst , src) pour créer une nouvelle tranche avec un en-tête différent tout en faisant référence au même tableau sous-jacent.
  • Envisagez d'utiliser la fonction make pour créer une tranche avec un longueur et capacité, évitant ainsi les frais liés à l'allocation et à la copie potentielle d'un nouveau tableau sous-jacent.

Comprendre les composants internes des tranches Go vous permet de tirer parti de leur flexibilité et de leur efficacité tout en garantissant que votre code se comporte comme prévu. En adoptant les nuances des en-têtes et des tableaux de tranches, vous pouvez maîtriser l'art du découpage dans Go et libérer tout le potentiel de cette structure de données polyvalente.

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