Mixing pointer and value receivers can be race-prone, because of the
copying involved in passing value receivers.

On Mon, Oct 7, 2024 at 12:03 PM 'Axel Wagner' via golang-nuts
<golang-nuts@googlegroups.com> wrote:
>
> To be honest, I always found this recommendation a little bit strange, 
> personally.
>
> I'll note that the standard library does not really keep to this either. For 
> example, time.Time.UnmarshalText (obviously) has a pointer-receiver, while 
> almost all other methods on time.Time have a value receiver.
> And if you implement flag.Value, the Set method obviously needs a pointer 
> receiver, but if the String method has one as well, it won't print properly 
> when used as a value. In basically every implementation of flag.Value I've 
> ever written, String needed a value receiver, while Set needed a pointer 
> receiver.
>
> I understand the basic idea of the advice, that if a type keeps state that is 
> manipulated via methods, then it should generally be passed around as a 
> pointer, so giving all the methods a pointer-receiver works well. But if a 
> type *is* intended to be used as a value (like time.Time or Enum in my 
> example) then you will almost certainly end up with a mix of receiver kinds - 
> as soon as you want to add any form of de-serialization to it. So "don't mix 
> receiver kinds" seems like misleading advice to me.
>
> On Mon, 7 Oct 2024 at 19:44, Ian Lance Taylor <i...@golang.org> wrote:
>>
>> On Mon, Oct 7, 2024 at 10:29 AM Ken Lee <ken.lee.kiany...@gmail.com> wrote:
>> >
>> > ---
>> > There is a consideration to make, though: historically it has been 
>> > considered bad form in Go to give a type a mix of value and pointer 
>> > receivers in methods without a very specific reason for doing so.
>> > ---
>> >
>> > Is this still the case now? As in 2024.
>>
>> As a general guideline, yes.
>>
>> https://go.dev/wiki/CodeReviewComments#receiver-type
>>
>> Ian
>>
>>
>>
>> > On Sunday 13 January 2013 at 7:03:29 am UTC+8 Kevin Gillette wrote:
>> >>
>> >> Indeed. In addition to implicit dereferencing for value receivers, the 
>> >> reverse also works as well: anything that is addressable (including 
>> >> 'value' variables on the stack, or a field of element of anything that's 
>> >> addressable) will implicitly be addressed when a pointer-receiver method 
>> >> is called on them (though you must explicitly use the address operator 
>> >> when you need to pass value variables as pointers).
>> >>
>> >> There is a consideration to make, though: historically it has been 
>> >> considered bad form in Go to give a type a mix of value and pointer 
>> >> receivers in methods without a very specific reason for doing so. The 
>> >> typical justification is that a small struct in a getter method might as 
>> >> well have a value receiver even though the corresponding setter method 
>> >> uses a pointer receiver; this, however, can lead to confusion on the part 
>> >> of the app programmer if they start out using only the read-only methods 
>> >> upon what turns out to be a value-copy of the original (but hey, it 
>> >> compiled and seems to work, so it must be correct) -- when use of 
>> >> pointer-receiver methods don't seem to produce the documented changes in 
>> >> the original, it can be difficult to debug.
>> >>
>> >>
>> >> On Saturday, January 12, 2013 3:17:16 PM UTC-7, Dave Collins wrote:
>> >>>
>> >>> On Saturday, January 12, 2013 3:52:35 PM UTC-6, Taric Mirza wrote:
>> >>>>
>> >>>> Thanks!  Works like a charm and is helping cleaning up my code a ton.
>> >>>>
>> >>>> One other question, this is really more about coding style:
>> >>>>
>> >>>> In the case where you manipulate members of the struct, then using
>> >>>> pointers as in your example is the way to go.
>> >>>>
>> >>>> But, you have a choice for functions that just read values from the
>> >>>> struct instead of manipulating it.  Is there a best practice coding
>> >>>> style here, between dereferencing the struct and then using that, or
>> >>>> dereferencing each member of the struct as you go?  eg:
>> >>>>
>> >>>> // A:
>> >>>>
>> >>>> laser := worldobj.(*Laser)
>> >>>> fmt.Printf("%0.4f,%0.4f", (*laser).x, (*laser).y)
>> >>>>
>> >>>> versus
>> >>>>
>> >>>> // B:
>> >>>>
>> >>>> laser := *(worldobj.(*Laser))
>> >>>> fmt.Printf("%0.4f,%0.4f", laser.x, laser.y)
>> >>>>
>> >>>>
>> >>>> I'm kind of torn.   I would imagine A) has slightly better
>> >>>> performance, and doesn't require any code-rework if you later on need
>> >>>> to manipulate the struct.
>> >>>>
>> >>>> On the other hand, B) is more readable since you don't have to look at
>> >>>> pointers all over the place, just on one line.
>> >>>
>> >>>
>> >>> Actually, you don't need to dereference at all.  Go automatically 
>> >>> handles this for you.
>> >>>
>> >>> See this example:  http://play.golang.org/p/ANaKaFSQLn
>> >>>
>> > --
>> > You received this message because you are subscribed to the Google Groups 
>> > "golang-nuts" group.
>> > To unsubscribe from this group and stop receiving emails from it, send an 
>> > email to golang-nuts+unsubscr...@googlegroups.com.
>> > To view this discussion on the web visit 
>> > https://groups.google.com/d/msgid/golang-nuts/03df7dce-5c48-44a3-bc3c-851ded2a1f08n%40googlegroups.com.
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "golang-nuts" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to golang-nuts+unsubscr...@googlegroups.com.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/golang-nuts/CAOyqgcX7v9Edk5beRH38tfJO18ZUXv-nOHsEPPCfMQy0hz%3DFdw%40mail.gmail.com.
>
> --
> You received this message because you are subscribed to the Google Groups 
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGcq2nxaik_qAWoX81W-tTKRRYBDM5_6%3DefSv4tr8b03g%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAMV2RqoQYRoVRB7fy%3DwUsngFjb0sJVwA39RwuO%3DYnhcWy%3Dp__A%40mail.gmail.com.

Reply via email to