Maison >développement back-end >Golang >Pourquoi la fonction My Go Struct Setter ne modifie-t-elle pas la structure d'origine ?

Pourquoi la fonction My Go Struct Setter ne modifie-t-elle pas la structure d'origine ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-21 10:00:17742parcourir

Why Doesn't My Go Struct Setter Function Modify the Original Struct?

Comprendre les setters pour les types de structure

Dans Go, les structures peuvent être modifiées via des fonctions de setter. Cependant, certains comportements peuvent être imprévus lors de l'utilisation de setters pour les types struct. Prenons l'exemple suivant :

package main

import "fmt"

type T struct { Val string }

// this setter seems not to work
func (t T) SetVal(s string) {
    t.Val = s
}

// this setter, using ptr to T, seems to work ok
func (t *T) SetVal2(s string) {
    (*t).Val = s
}

func main() {
    v := T{"abc"}
    fmt.Println(v)        // prints {abc}
    v.SetVal("pdq")
    fmt.Println(v)        // prints {abc}, was expecting {pdq}!
    v.SetVal2("xyz")
    fmt.Println(v)        // prints {xyz}!
}

La question se pose : pourquoi la fonction SetVal ne modifie-t-elle pas la structure d'origine comme prévu ?

Comprendre la sémantique des valeurs

La principale différence réside dans la façon dont les structures sont transmises aux fonctions. Lors du passage d'une structure par valeur (comme dans SetVal), une copie de la structure est créée dans la fonction. Toute modification apportée au sein de la fonction n'affectera que cette copie temporaire, laissant la structure d'origine inchangée.

Cependant, lors du passage d'une structure par pointeur (comme dans SetVal2), la fonction accède à la structure d'origine en mémoire. Toute modification apportée au sein de la fonction sera directement reflétée dans la structure d'origine.

Sémantique de preuve de valeur

Cela peut être illustré en imprimant les adresses mémoire des structures impliquées :

package main

import "fmt"

type T struct { Val string }

func (t T) SetVal(s string) {
    fmt.Printf("Address of copy is %p\n", &t)
}

func (t *T) SetVal2(s string) {
    fmt.Printf("Pointer argument is %p\n", t)
}

func main() {
    v := T{"abc"}
    fmt.Printf("Address of v is %p\n", &v)
    v.SetVal("pdq")
    v.SetVal2("xyz")
}

Ce code produira une sortie ressemblant à :

Address of v is 0xf840001290
Address of copy is 0xf8400013e0
Pointer argument is 0xf840001290

Notez que le premier et les troisièmes adresses imprimées sont les mêmes, indiquant qu'elles font référence à la même structure. Cependant, la deuxième adresse est différente, représentant la copie temporaire créée dans SetVal.

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