The Go FAQ answers a question regarding the choice of by-value vs. by-pointer receiver definition in methods. One of the statements in that answer is:
If some of the methods of the type must have pointer receivers, the rest should too, so the method set is consistent regardless of how the type is used.
This implies that if I have for a data type a few methods that mutate the data, thus require by-pointer receiver, I should use by-pointer receiver for all the methods defined for that data type.
On the other hand, the "fmt"
package invokes the String()
method as defined in the Stringer
interface by value. If one defines the String()
method with a receiver by-pointer it would not be invoked when the associated data type is given as a parameter to fmt.Println
(or other fmt
formatting methods). This leaves one no choice but to implement the String()
method with a receiver by value.
How can one be consistent with the choice of by-value vs. by-pointer, as the FAQ suggests, while fulfilling fmt
requirements for the Stringer
interface?
EDIT:
In order to emphasize the essence of the problem I mention, consider a case where one has a data type with a set of methods defined with receiver by-value (including String()). Then one wishes to add an additional method that mutates that data type - so he defines it with receiver by-pointer, and (in order to be consistent, per FAQ answer) he also updates all the other methods of that data type to use by-pointer receiver. This change has zero impact on any code that uses the methods of this data type - BUT for invocations of fmt
formatting functions (that now require passing a pointer to a variable instead of its value, as before the change). So consistency requirements are only problematic in the context of fmt
. The need to adjust the manner one provides a variable to fmt.Println
(or similar function) based on the receiver type breaks the capability to easily refactor one's package.