Understanding ""cannot take the address of"" and ""cannot call pointer method on"" in Go
Despite the similar functionality of the code snippets, one compiles and works while the other generates errors:
// This compiles and works diff := projected.Minus(c.Origin) dir := diff.Normalize() // This does not (yields the errors in the title) dir := projected.Minus(c.Origin).Normalize()
The disparity is attributed to the difference in receiver types for the Normalize() method.
Receiver Types in Go Methods
Go methods can have either a value receiver or a pointer receiver. A value receiver operates on a copy of the struct while a pointer receiver operates on the original struct itself.
In the case of Normalize(), it has a pointer receiver, requiring a pointer to a Vector3 value as the receiver.
Addressing Variables and Return Values
Variables in Go are addressable, meaning the address of a variable can be taken to pass as an argument to a pointer receiver method. However, the return values of function and method calls are not addressable.
Chain Calls with Pointer Receivers
In the example where it compiles, the compiler automatically takes the address of the diff variable to match the pointer receiver of Normalize().
In the example where it does not compile, the compiler cannot automatically take the address of the return value of Minus() since it is not addressable. The return value being a copy, it must be assigned to a variable first, so that its address can be taken.
Workarounds
Several workarounds exist to resolve the issue:
Consistency in Receiver and Result Types
It is advisable to maintain consistency in receiver and result types throughout a custom type. If most methods have pointer receivers, all methods should use pointer receivers. Similarly, if most methods return pointers, all methods should return pointers.
The above is the detailed content of Why Does Chaining Method Calls Fail with Pointer Receivers in Go?. For more information, please follow other related articles on the PHP Chinese website!