Méthodes de réception appelant une confusion syntaxique dans Go
Lors de l'exploration des différences entre les pointeurs et les valeurs pour les récepteurs, il est à noter que les méthodes de valeur peuvent être invoquées à la fois sur les pointeurs et les valeurs, tandis que les méthodes de pointeur sont limitées aux pointeurs uniquement. Cette restriction provient de la capacité des méthodes de pointeur à modifier le récepteur, ce qui entraîne l'abandon des modifications si elles sont invoquées sur une copie de la valeur.
Cependant, un exemple de code présentant une méthode de pointeur appelée sur une valeur provoque une confusion. Le code est le suivant :
<code class="go">package main import ( "fmt" "reflect" ) type age int func (a age) String() string { return fmt.Sprintf("%d year(s) old", int(a)) } func (a *age) Set(newAge int) { if newAge >= 0 { *a = age(newAge) } } func main() { var vAge age = 5 pAge := new(age) fmt.Printf("Type information:\n\tvAge: %v\n\tpAge: %v\n", reflect.TypeOf(vAge), reflect.TypeOf(pAge)) fmt.Printf("vAge.String(): %v\n", vAge.String()) fmt.Printf("vAge.Set(10)\n") vAge.Set(10) fmt.Printf("vAge.String(): %v\n", vAge.String()) fmt.Printf("pAge.String(): %v\n", pAge.String()) fmt.Printf("pAge.Set(10)\n") pAge.Set(10) fmt.Printf("pAge.String(): %v\n", pAge.String()) }</code>
Malgré la documentation indiquant que cela ne devrait pas être possible, ce code se compile et s'exécute sans erreur. Alors, quelle est la cause de cette apparente incohérence ?
La réponse réside dans le concept de valeurs adressables. La spécification Go définit qu '"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ée à la liste de paramètres de m." De plus, "Si x est adressable et que l'ensemble de méthodes de &x contient m, x.m() est un raccourci pour (&x).m()."
Dans ce cas, vAge est adressable, ce qui signifie qu'il a une adresse mémoire valide . Lors de l'appel de vAge.Set(), le compilateur reconnaît que la méthode de réception du pointeur Set() peut également être invoquée en utilisant l'adresse de la valeur, ce qui est équivalent à (&vAge).Set().
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!