Maison  >  Article  >  développement back-end  >  Quel est le mystère derrière le comportement des tranches dans les opérations append() dans Go ?

Quel est le mystère derrière le comportement des tranches dans les opérations append() dans Go ?

Barbara Streisand
Barbara Streisandoriginal
2024-10-23 13:45:02980parcourir

What's the Mystery Behind Slice Behavior in append() Operations in Go?

Démystifier le comportement de append() sur les Slices

Dans Go, il est courant de rencontrer du code comme celui-ci :

<code class="go">func main() {
    slice := make([]int, 10, 10)
    slice[0] = 0
    slice[1] = 1

    slice1 := slice
    slice1[0] = 10000
    fmt.Println(slice)

    slice1 = append(slice1, 100)
    slice1[0] = 20000

    fmt.Println(slice)
}</code>

Lors de l'exécution ce code, vous remarquerez quelque chose de particulier :

[10000 1 0 0 0 0 0 0 0 0]
[10000 1 0 0 0 0 0 0 0 0]

Intuitivement, on pourrait supposer que slice et slice1 sont des références au même tableau sous-jacent. Cependant, cette observation soulève la question : pourquoi slice reste-t-il inchangé après l'opération d'ajout sur slice1 ?

Comprendre la nature des tranches

Pour percer ce mystère, il est essentiel comprendre la nature fondamentale des slices dans Go. Les tranches ne sont pas des pointeurs ; ce sont des encapsulations d'un tableau. Concrètement, une slice comprend trois éléments :

  • Pointeur vers le début du tableau sous-jacent
  • Taille de la slice
  • Capacité de la slice (taille maximale sans réallocation )

Lors de l'attribution de slice1 à slice, vous créez un nouvel en-tête de tranche qui pointe vers le même tableau sous-jacent que slice. En conséquence, toutes les modifications apportées à slice1 sont directement reflétées dans slice.

L'impact de append()

Analysons maintenant l'impact de append() sur tranche1. La fonction append() prend une tranche comme argument et renvoie une nouvelle tranche. Cette nouvelle tranche peut ou non faire référence au même tableau sous-jacent que la tranche d'origine.

Dans ce cas, puisque la tranche a initialement une capacité égale à sa longueur, toute opération append() avec plus de 0 élément nécessite créer un nouveau tableau plus grand. C'est précisément ce que fait slice1 = append(slice1, 100). Il alloue un nouveau tableau, copie le contenu de l'ancien et renvoie un nouvel en-tête de tranche.

L'affectation de l'en-tête de tranche résultant à slice1 remplace l'en-tête de tranche précédent dans slice1. Cela signifie que slice1 pointe désormais vers un tableau sous-jacent différent de celui de slice. Par conséquent, toute modification ultérieure apportée à slice1 n'affecte pas slice, et vice versa.

Conclusion

Bien que les tranches puissent être généralement confondues avec des pointeurs, elles sont en réalité des valeurs distinctes genres. Cette différence intrinsèque se manifeste lors des opérations append(). Les affectations telles que slice1 = append(slice1, 100) créent un nouvel en-tête de tranche qui peut ou non pointer vers le même tableau sous-jacent que la tranche d'origine. Il est essentiel de garder cela à l’esprit lors de la manipulation de tranches dans le code Go.

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