Maison > développement back-end > Golang > Pourquoi l'ajout à une tranche dans une boucle affecte-t-il les autres tranches dans Go ?

Pourquoi l'ajout à une tranche dans une boucle affecte-t-il les autres tranches dans Go ?

Barbara Streisand
Libérer: 2024-11-06 04:05:02
original
1044 Les gens l'ont consulté

Why Does Appending to a Slice in a Loop Affect Other Slices in Go?

Comportement inattendu dans Slice Append : comment créer plusieurs tranches sans problèmes de modification

Lors de la manipulation de tranches dans le code Go, vous pouvez rencontrer un problème déroutant problème : l'ajout d'éléments à une tranche dans une boucle, puis l'utilisation du résultat de la boucle pour créer de nouvelles tranches peuvent entraîner le remplacement du dernier ajout par les tranches des ajouts précédents. Ce comportement se produit car les tranches font référence aux mêmes valeurs de tableau sous-jacentes.

Exemple :

<code class="go">func create(iterations int) []int {
    a := make([]int, 0)
    for i := 0; i < iterations; i++ {
        a = append(a, i)
    }
    return a
}

func sliceFromLoop() {
    i := create(11)
    j := append(i, 100)
    g := append(i, 101)
    h := append(i, 102)
    fmt.Printf("i: %v\nj: %v\ng: %v\nh:%v\n", i, j, g, h)
}</code>
Copier après la connexion

Dans cet exemple, la fonction sliceFromLoop crée une tranche i et ajoute différentes valeurs, ce qui donne les tranches j, g et h. Cependant, les trois tranches pointent vers le même tableau sous-jacent, donc lorsque le dernier ajout modifie le tableau, cela affecte toutes les tranches.

Solution : copier des tranches pour des modifications indépendantes

La manière idiomatique de créer plusieurs tranches basées sur une tranche existante et d'éviter les problèmes de modification consiste à copier la tranche avant d'ajouter quoi que ce soit. Cela garantit que chaque nouvelle tranche a son propre tableau sous-jacent.

<code class="go">func makeFromSlice(sl []int) []int {
    result := make([]int, len(sl))
    copy(result, sl)
    return result
}</code>
Copier après la connexion

Exemple d'utilisation :

<code class="go">func main() {
    i := make([]int, 0)
    for ii := 0; ii < 11; ii++ {
        i = append(i, ii)
    }
    j := append(makeFromSlice(i), 100) // works fine
}</code>
Copier après la connexion

Dans cet exemple révisé, nous créons une copie du je tranche avant d'y ajouter 100. Cela garantit que j fait référence à un tableau sous-jacent distinct et ne sera pas affecté par les modifications futures de i.

Explication du comportement littéral de Slice

La raison pour laquelle ce problème se produit ne se produit pas avec les littéraux de tranche (par exemple, i := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), c'est qu'un nouveau tableau est alloué si l'opération d'ajout le permet dépasser la capacité de la baie de support. Ce comportement n'a aucun rapport avec les littéraux de tranche et constitue une propriété fondamentale de l'ajout aux tranches.

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