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/6c1421bf-d16d-4b18-9117-91b286c95e76n%40googlegroups.com.