Go Receiver Methods Calling Syntax: A Deeper Dive
In the "Effective Go" guide, it is stated that pointer methods can only be invoked on pointers, while value methods can be invoked on either pointers or values. However, a recent encounter poses a question: why does a value invoke a pointer method in the following code?
<code class="go">package main import ( "fmt" ) 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) vAge.Set(10) // Compilation successful }</code>
To resolve this, we turn to the Go language specification. Under "Calls," it says:
A method call x.m() is valid if the method set of (the type of) x contains m and the argument list can be assigned to the parameter list of m. If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m().
In our case, vAge is addressable (a type conversion to *age is valid), so vAge.Set(10) is essentially (&vAge).Set(10). Since the receiver type of Set() is a pointer, this is why the value vAge can invoke the pointer method Set().
The above is the detailed content of ## Why Can a Value Invoke a Pointer Method in Go?. For more information, please follow other related articles on the PHP Chinese website!