Dans la section « Pointeurs contre valeurs » d'Effective Go, il est indiqué que « les méthodes de valeur peuvent être invoquées sur des pointeurs et des valeurs , mais les méthodes de pointeur ne peuvent être invoquées que sur des pointeurs." Cela est dû au fait que les méthodes de pointage peuvent modifier le récepteur, et les invoquer sur une copie de la valeur entraînerait l'annulation de ces modifications.
Cependant, certains développeurs ont rencontré une situation où ils ont pu invoquer une méthode de pointeur sur une valeur, ce qui semble contredire les règles de syntaxe documentées. Pour clarifier cette confusion, nous allons explorer ce comportement plus en détail.
Considérez le code Go suivant :
<code class="go">package main import ( "fmt" "reflect" ) type age int func (a age) String() string { return fmt.Sprintf("%d yeasr(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("TypeOf =>\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>
Dans cet exemple, nous définissons un type d'âge avec deux méthodes : String( ) (méthode valeur) et Set() (méthode pointeur). Le code crée deux variables : vAge, une valeur de type age, et pAge, un pointeur vers une valeur d'âge.
Malgré la documentation indiquant que vAge.Set() ne doit pas être une syntaxe valide, le code se compile sans erreurs. En effet, vAge est adressable, ce qui signifie qu'il possède une adresse mémoire qui peut être référencée. Conformément à la spécification du langage, un appel de méthode x.m() sur une variable adressable x est valide si l'ensemble de méthodes de x contient m.
Dans ce cas, vAge est adressable, et puisque l'ensemble de méthodes de *age contient Set (), l'appel à vAge.Set() est une notation abrégée pour (&vAge).Set(). Essentiellement, le & L'opérateur est utilisé implicitement pour obtenir le pointeur vers vAge.
Par conséquent, le code démontre que les méthodes de valeur peuvent effectivement être invoquées sur des pointeurs car les invoquer sur une valeur adressable équivaut à appeler la méthode sur un pointeur vers celle-ci. valeur. La méthode pointeur Set() n'est encore invocable que sur les pointeurs, mais dans le cas où la valeur est adressable, le déréférencement implicite permet que la syntaxe vAge.Set() soit valide.
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!