Historique de la question :
Go a été conçu comme un langage avec une sémantique de valeur explicite : presque tout est copié par valeur lors du passage, y compris les structures (struct), mais pas les pointeurs et les tranches (slice). Cela a simplifié le raisonnement et amélioré la sécurité, mais a introduit un certain nombre de "pièges".
Problème :
Souvent, les développeurs s'attendent à ce que les modifications d'une structure passées à une fonction soient visibles à l'extérieur. Mais tout le contenu est copié (y compris les champs imbriqués - par valeur !). Pour les tranches et les maps, le comportement est différent, où seul le "conteneur" est copié, mais pas le "contenu".
Solution :
Passez de grandes structures par pointeur si un changement est attendu. Pour les slices, seul le descripteur (length, capacity, pointer) est copié, pas le contenu - les modifications de la tranche originale (via un index) seront visibles à l'extérieur. Pour les structs - tout est copié :
type Point struct { X, Y int } func move(p Point) { p.X = 100 } func movePtr(p *Point) { p.X = 100 } func demo() { pt := Point{10, 10} move(pt) fmt.Println(pt.X) // 10 movePtr(&pt) fmt.Println(pt.X) // 100 }
Caractéristiques clés :
Si vous modifiez une structure à l'intérieur d'une fonction, l'original changera-t-il ?
Non, si la structure est passée par valeur - les modifications sont locales.
type User struct {Name string} func f(u User) {u.Name = "Ann"}
Si vous modifiez un élément de la tranche à l'intérieur d'une fonction, l'original changera-t-il ?
Oui. Les tranches sont une "vue" sur un tableau partagé. En modifiant un élément, vous modifiez également les données originales.
func f(s []int) {s[0] = 99}
Que se passera-t-il si vous renvoyez une tranche créée à l'intérieur d'une fonction ?
La "tête" de la tranche est copiée, mais le tableau sous-jacent reste accessible. Si vous ne conservez pas la référence à l'extérieur, les données peuvent être collectées par le GC.
Dans la fonction, le traitement de la structure User se faisait par valeur - les modifications ne revenaient pas, les bugs étaient difficiles à identifier.
Avantages :
Inconvénients :
De grandes structures sont clairement passées par pointeur, et pour les slices, le comportement est toujours commenté ou vérifié. Pas de confusion, tout le monde attend la sémantique de valeur.
Avantages :
Inconvénients :