Maison  >  Article  >  développement back-end  >  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
Barbara Streisandoriginal
2024-11-06 04:05:02961parcourir

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>

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>

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>

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!

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