I generally understand what pointers are and how they work. Where I run into trouble is when to use them in my own code.
When I have a struct that I want to create a new instance of, when should I return the instance and when should I return it as a pointer? Say I have a function to get a Session
instance in a web app. It either looks up the session from a cookie or creates a new one. In any situation it will always return a valid Session. Should this return Session
or *Session
? Why?
Now consider a card game that has Card
, Deck
, and Hand
structs. When creating a Hand
, a Card
is removed from the Deck
and put in a Hand
. There can only ever be 1 instance of a particular Card
, such as 8 of hearts, should Card
be passed around as a pointer? Would this be more memory efficient? Is there a concern about garbage collection here? Or can the GC still keep track of memory only being passed as a pointer?
My experience is in languages like Java, Ruby, Lua, Php, if that helps know where I'm coming from.
Top comments (6)
It depends on the use case which approach you would choose.
Passing structs by value creates a new copy as well as memory position, it is placed on the stack. Stack is cheap.
Passing by reference, the pointer points to the original struct and memory position, it is placed on the heap. Heap is expensive.
So, if your struct is large or if you want to modify the values of the original struct down the line, then you go with pointers, otherwise stick with values.
That's the simple version :D
Excellent point about the Heap vs Stack. I keep expecting pointers would be more efficient, not thinking of values being on the Stack.
The general best practice is that you should use pointers if you want to modify the struct, values if you don't. You should also use a pointer if the struct is big. There's no rule applicable 100% of the times though. The go wiki has a really good summary on cases about receivers.
The same rules apply to return values. This is a great answer about all things pointers and values and builtin and custom types: stackoverflow.com/a/23551970/4186181
So, to anwser your direct questions:
The caller is probably not going to modify the session and if the session is not a massive struct, go with values
This sounds like a great case to use a pointer. Various methods modify the same instance so you shall pass around it as a pointer. It's memory efficient and GC is not going to matter since you need that instance during your program lifetime. There are going to be concurrency concerns if multiple goroutines access the same object, but that's another story (and you'd have the same access control issues with all languages) :D
Hope this helps
There is a good read here
ardanlabs.com/blog/2017/05/languag...
I'd highly, highly recommend these questions from the FAQs:
golang.org/doc/faq#Pointers
This is good info but doesn't seem to answer my questions about pointers and structs.