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.