Maison > développement back-end > Golang > Pourquoi une méthode Go avec un récepteur pointeur modifie-t-elle un argument non-pointeur ?

Pourquoi une méthode Go avec un récepteur pointeur modifie-t-elle un argument non-pointeur ?

Barbara Streisand
Libérer: 2024-12-05 11:35:11
original
484 Les gens l'ont consulté

Why Does a Go Method with a Pointer Receiver Modify a Non-Pointer Argument?

Pourquoi la méthode avec récepteur de pointeur change toujours de valeur lorsqu'elle reçoit un non-pointeur ?

Dans Go, les méthodes avec des récepteurs de pointeur sont connues pour conserver les valeurs d'origine des variables qu'elles exploitent sur. Cependant, il semble y avoir une contradiction apparente lorsqu'une méthode attend un argument de pointeur et reçoit une valeur autre qu'un pointeur.

Considérez l'extrait ci-dessous pour l'exercice 51 du Tour of Go :

func (v *Vertex) Scale(f float64) {
    v.X *= f
    v.Y *= f
}

func main() {
    v := &Vertex{3, 4}
    v.Scale(2)
    fmt.Println(v) // Output: &{6 8}
}
Copier après la connexion

D'après l'explication, la méthode Scale ne devrait pas modifier v puisqu'elle reçoit un pointeur vers un Vertex (*Vertex) au lieu d'un Vertex lui-même.

Cependant, lorsque nous changeons la ligne v := &Vertex{3, 4} en v := Vertex{3, 4} dans main, la sortie passe de &{6 8} à {6 8 } (remarquez le & manquant). Cela indique que v a été modifié, même s'il a été transmis comme valeur non-pointeur.

L'explication

La clé réside dans la nature fortement typée de Go et dans les optimisations du compilateur. Même si la méthode Scale attend un récepteur de pointeur, elle peut toujours accepter des valeurs autres que des pointeurs car Go les convertit implicitement en pointeurs.

Plus précisément, le compilateur réécrit le code suivant :

v := Vertex{3, 4}
v.Scale(2)
Copier après la connexion

to :

(&v).Scale(2)
Copier après la connexion

Cela signifie que la méthode est en fait appelée avec un pointeur vers v, ce qui lui permet de modifier l'original value.

La règle spécifique à Go suivante explique ce comportement :

Un appel de méthode x.m() est valide si l'ensemble de méthodes de (le type de) x contient m et que la liste d'arguments peut être affecté à la liste de paramètres de m. Si x est adressable et que l'ensemble de méthodes de &x contient m, x.m() est un raccourci pour (&x).m().

En résumé, les méthodes avec des récepteurs de pointeurs peuvent toujours modifier les variables non-pointeurs car le compilateur convertit automatiquement vers des pointeurs pour préserver la sécurité des types de méthodes.

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!

source:php.cn
Déclaration de ce site Web
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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal