Maison >développement back-end >Golang >Pourquoi l'ajout à une tranche dans une boucle produit-il des résultats inattendus en Go ?

Pourquoi l'ajout à une tranche dans une boucle produit-il des résultats inattendus en Go ?

DDD
DDDoriginal
2024-11-03 04:57:311168parcourir

Why Does Appending to a Slice in a Loop Produce Unexpected Results in Go?

Comportement inattendu lors des opérations d'ajout sur des tranches

Dans Go, un comportement inattendu peut se produire lors de l'ajout d'éléments à des tranches lors d'itérations de boucle, puis de la création de nouveaux tranches en fonction des résultats. Ce comportement découle du tableau sous-jacent qui coupe la référence.

Considérez le code suivant :

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

Si nous appelons create(11) et attribuons le résultat à i, nous attendons chaque ajout suivant opération (j := append(i, 100), g := append(i, 101) et h := append(i, 102)) pour créer de nouvelles tranches avec des valeurs distinctes. Cependant, le comportement observé est que le dernier élément de ces nouvelles tranches est toujours 102, quel que soit leur index.

Cela se produit car tous les ajouts modifient le même tableau sous-jacent. L'ajout d'un élément à la tranche modifie la longueur et peut entraîner une réallocation du tableau. Lorsqu'un nouveau tableau est alloué, toutes les références précédentes à l'ancien tableau deviennent invalides.

Les littéraux de tranche, cependant, se comportent comme prévu car un nouveau tableau est toujours alloué si l'ajout dépasse la capacité du tableau de sauvegarde.

Approche idiomatique

Pour garantir un comportement prévisible lors de la création de plusieurs nouvelles tranches basées sur une tranche existante, l'approche idiomatique consiste à copier la tranche avant d'ajouter des éléments :

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

En effectuant une copie, nous créons un nouveau tableau de sauvegarde et veillons à ce que les modifications apportées à la tranche résultante n'affectent pas la tranche d'origine.

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