On Tuesday, 10 August 2021 at 22:50:00 UTC+1 lege...@gmail.com wrote:

> And I'm still a little confused here, you know when we use the struct 
> method directly, it is only when the function is called that the type of 
> receiver determines whether the passed struct is a pointer or a copied 
> value. But when using a function pointer, why does it decide whether to 
> bind a pointer or a copied value at the time of assignment, but not at the 
> time of function called? 
>
>
Neither is true.

In go, *all* arguments are passed by value.  If the argument is a struct, 
then the struct is copied.  If the argument is a pointer, then the pointer 
is copied.

Ignoring methods for a moment, just consider these simple functions:

func Display1(z Zoo) { ... }
func Display2(z *Zoo) { ... }

v := Zoo{....}
Display1(v)   # v is copied
vp := &Zoo
Display2(vp)  # vp is copied

These are identical, consistent behaviours.

So now onto "pointer to function".  You are thinking like C.  In Go there 
is no meaningful "pointer to function", there are just "function values":
https://play.golang.org/p/Q6GogYU8f

Internally of course, a function value will contain some sort of pointer to 
the code, just as a string value contains a pointer to the string, and a 
slice value contains a pointer to the slice backing array. (In the latter 
two cases the pointer may be nil if the len or cap is zero, and the overall 
value is still valid).  When you pass a string or a slice to a function, 
you are copying this structure with its embedded pointer/len/cap,  These 
pointers are implementation details, and are not directly accessible to the 
user program - at least not in a "safe" way.

Whether the function takes zero arguments, one or more arguments, whether 
those arguments are structs or pointers or chans or whatever, affects the 
*type* of the value and hence how you call it, but otherwise a function 
value is just a value.

So finally we get to methods:
https://play.golang.org/p/TAPCwDvxxbo

If you take a method value (pf := gz.Display), you are just getting a 
function value, where the special first argument of the function has been 
bound ("curried") to some value.

If the method takes a "Zoo" receiver, then the value is bound to a copy of 
the Zoo value.  If the method takes a "*Zoo" receiver, then the value is 
bound to a copy of the pointer-to-Zoo value.  Again, this is 100% 
consistent.  The function always receives a copy of the value, of the type 
of the argument.

There is just one bit of magic, which is the automatic referencing and 
dereferencing.  Very roughly speaking: if a method takes a *Zoo but you 
apply it to a Zoo value, or vice versa, the value is converted from Zoo to 
pointer-to-Zoo or vice versa as required.

But the value which is received by the method is always of the type it 
declares: func (z Zoo) Display() always takes a copy of a Zoo value, and 
func (z *Zoo) Display() always takes a copy of a pointer-to-Zoo value.  The 
value is always copied, and this is done at the time the method value is 
created, not the time at which it is called (which may be never, or may be 
many times).

-- 
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/34c3fc58-4bdf-4dc0-bd13-a675be4d0f29n%40googlegroups.com.

Reply via email to