Go Pointers: Memory Addresses, Not Math
Go pointers are street addresses for data. Instead of copying a large struct, you pass its memory address. This lets functions modify the original value and is critical for performance.
Why it exists
Go needed a way for functions to modify arguments and to avoid the high cost of copying large data structures. Pointers provide a way to pass a reference to a value's location in memory, rather than copying the entire value itself, striking a balance between performance and safety.
The mental model
Think of a pointer as a street address for a piece of data. A variable holds a value (the contents of a house), while a pointer holds the address of that variable (the house's street address). To see what's inside the house, you have to go to the address; this is called dereferencing.
How it works
Go uses two main operators for pointers. The address operator, &, gives you the memory address of a variable. If v is an int, then p := &v creates a pointer p of type int that holds the address of v. The indirection or dereferencing operator, , accesses the value at a pointer's address. So *p gives you the value of v. Unlike C or C++, Go does not allow pointer arithmetic. You cannot increment a pointer to access the next memory location, which eliminates a whole class of bugs.
When to use it
Use pointers in three main scenarios. First, when you want a function to be able to modify the value of a variable that was passed to it. Second, when you are passing a large struct to a function and want to avoid the performance overhead of making a copy. Third, when defining methods on a type that need to mutate the receiver's state (e.g., func (s *MyStruct) changeState()).
When not to use it
Avoid pointers for basic types (like int, bool, string) or small structs where the cost of copying is negligible. Passing by value is often simpler and safer, as it prevents unintended side effects from shared mutable state. Don't use a pointer just because you can; use it when you need to share or modify data.
One canonical example
To allow a function to modify a caller's variable, you pass a pointer to it. For example, a function to increment a number: func increment(n int) { n = *n + 1 }. You would call it like this: i := 10; increment(&i);. After the call, the value of i in the calling function would be 11, because increment modified the original variable directly via its memory address.
Interview question
Which scenario best justifies using a pointer in Go?
- a.Ensuring a function receives a completely independent copy of a variable.
- b.Storing a small integer value that will be frequently accessed.
- c.Passing a large data structure to a function to prevent expensive copying.Correct
- d.Performing arithmetic operations on memory addresses to navigate data arrays.
Why? this is the answer
The card states that a key reason to use pointers is "when you are passing a large struct to a function and want to avoid the performance overhead of making a copy." Option A describes pass-by-value behavior, which is the opposite of using a pointer to share or modify the original data.
Just read this? Test yourself on what you have been reading.
Read the original → go.dev
- #go
- #pointers
- #memory-management
- #performance
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on go — each one lists the topics its interview covers.
See open roles