I learn k8s sdk source code has a question,when a method return point type,the caller can direct use method return value without using * get the value,
why, the demo code,direct use pods,not *pods
CodePudding user response:
That's one of the differences between go and other (mostly older) languages in the C family. In some languages, you need to use a dedicated operator to access fields on objects that through indirection (ie pointers), in golang, the dot operator handles both.
In case someone stumbles across this question and doesn't know what this all means: If you had a pointer to a type like this in C:
typedef struct pod_list {
item items[100]; // or something
} pod_list;
You would need to write the following to access the items
array:
item * an_item = pods->items[1];
Or you'd need to dereference the pointer first, then access the array directly:
item *an_item = (*pods).items[1]; // can't remember off the top of my head if the brackets are needed here though
Golang has an arrow operator, but it's used to write to channels:
ch := make(chan struct{}, 1)
ch <- struct{}{}
Or specify channel directionality when passing it as an argument:
func doStuff(ctx context.Context, ch chan<- struct{}) {
// this function can only write to the channel
}
func doMoreStuff(ctx context.Context, ch <-chan struct{}) {
// this function can only read from the channel
}
When it comes to accessing fields of objects, the .
operator handles both direct and indirect access. I had a quick look on the golang pages to see if they elaborate on this design decision, and found this line on the golang tour page about accessing struct fields:
To access the field
X
of a struct when we have the struct pointerp
we could write(*p).X
. However, that notation is cumbersome, so the language permits us instead to write justp.X
, without the explicit dereference.
So the TL;DR is this: you could write (*pods).Items
and explicitly dereference the pointer, but it's simply not needed. Having written a fair bit of C before moving to golang, I initially thought I'd prefer the explicit nature of the arrow operator, because I like knowing whether a variable is a pointer or not. Then again, after a few years, I can't say I miss the faffing around with dereferencing, arrow operators, let alone multiple levels of indirection. 99% of the time, if the code is well written, you know what is a pointer and what isn't anyway.