Home >Backend Development >Golang >## Why Can I Call a Pointer Method on a Value in Go?
Receiver Methods Calling Syntax Confusion in Go
When exploring the differences between pointers and values for receivers, it is noted that value methods can be invoked on both pointers and values, while pointer methods are restricted to pointers only. This restriction stems from the ability of pointer methods to modify the receiver, resulting in discarded modifications if invoked on a copy of the value.
However, a code example showcasing a pointer method being called on a value causes confusion. The code is as follows:
<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>
Despite the documentation stating that it should not be possible, this code compiles and runs without errors. So, what is causing this apparent inconsistency?
The answer lies within the concept of addressable values. The Go specification defines that "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." Additionally, "If x is addressable and &x's method set contains m, x.m() is shorthand for (&x).m()."
In this case, vAge is addressable, meaning it has a valid memory address. When calling vAge.Set(), the compiler recognizes that the pointer receiver method Set() can also be invoked using the address of the value, which is equivalent to (&vAge).Set().
The above is the detailed content of ## Why Can I Call a Pointer Method on a Value in Go?. For more information, please follow other related articles on the PHP Chinese website!