Perhaps this section of the spec will 
help: https://golang.org/ref/spec#Method_declarations

> The type of a method is the type of a function with the receiver as first 
argument

So there's only a single copy of the function code, but the argument passed 
to it is copied
>From your original example: `gz.Display() == Zoo.Display(*gz)`

On Wednesday, August 11, 2021 at 7:59:57 PM UTC+2 lege...@gmail.com wrote:

> Thank you so much. 
>
> Your explanation makes my understanding of this problem more and more 
> clear.
>
> However, since I have been a C programmer for a long time, I still don't 
> understand the implementation of the function variable in Golang very well. 
> I think I need to do some inspection about function variable in Golang to 
> know more details.
>
> On Wednesday, August 11, 2021 at 1:23:44 AM UTC-7 Brian Candler wrote:
>
>> 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/dc60e8c5-1d48-4ce1-8181-1557f0db3a65n%40googlegroups.com.

Reply via email to