DEV Community

MN Mark
MN Mark

Posted on

Pointers in practice

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.

Discussion (6)

Collapse
jaakidup profile image
Jaaki

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

Collapse
mjb2kmn profile image
MN Mark Author

Excellent point about the Heap vs Stack. I keep expecting pointers would be more efficient, not thinking of values being on the Stack.

Collapse
rhymes profile image
rhymes

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:

In any situation it will always return a valid Session. Should this return Session or *Session? Why?

The caller is probably not going to modify the session and if the session is not a massive struct, go with values

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?

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

Collapse
theodesp profile image
Theofanis Despoudis

There is a good read here
ardanlabs.com/blog/2017/05/languag...

Collapse
val_baca profile image
Valentin Baca

I'd highly, highly recommend these questions from the FAQs:
golang.org/doc/faq#Pointers

Collapse
mjb2kmn profile image
MN Mark Author

This is good info but doesn't seem to answer my questions about pointers and structs.