(X) The Proper Use of Pointers in Go
(X) The Proper Use of Pointers in Go
Go has become increasingly popular in recent years, especially in my local area. It has
been consistently displacing other backend languages like Ruby, Python, C# and Java.
Go is wanted for its simplicity, explicitness, speed, and low memory consumption.
Many developers that are new to the language, or new to a language that can handle
memory directly using pointers end up misusing those pointers.
What Is a Pointer?
A pointer is a variable that stores the address of a value, rather than the value itself. If you
think of a computer’s memory (RAM) as a JSON object, a pointer would be like the key,
and a normal variable would be the value.
{
"pointer": "variableValue"
}
package main
import "fmt"
func main() {
// create a normal string variable
name := "original"
// pass in a pointer to the string variable using '&'
setName(&name, "boot.dev")
fmt.Println(name)
}
boot.dev
As you can see, because we have a pointer to the address of the variable, we can modify
its value, even within the scope of another function. If the value were not a pointer, this
would not work:
package main
import "fmt"
func main() {
name := "original"
setNameBroken(name, "boot.dev")
fmt.Println(name)
}
prints:
original
Pointers can be useful, but in the same way that they are useful, they can be dangerous.
For example, if we dereference a pointer that has no value, the program will panic. For
this reason, we always check if an error value is nil before trying to print it.
Syntax
1. Creating a pointer: &
newString := ""
newStringPointer := &newString
import "fmt"
func main() {
newString := ""
newStringPointer := &newString
fmt.Println(newStringPointer)
}
prints: 0xc00000e1e0
2. Describing a pointer: *
3. Dereferencing a pointer: *
It can be slightly confusing, but the * is used to describe a pointer and it is also used as
an operator to dereference a pointer.
2. Better Performance
If you have a string that contains an entire novel in memory it gets really expensive to
copy that variable each time it is passed to a new function. It may be worthwhile to pass a
pointer instead, which will save CPU and memory. This comes at the cost of readability
however, so only make this optimization if you must.
Sometimes a function needs to know what something’s value is, as well as if it exists or
not. I usually use this when decoding JSON to know if a field exists or not. For example, if
a JSON object is:
These are some rules of thumb for when to use pointers in your code. If you are unsure,
and a normal value will work just fine, I would advise avoiding the pointer. Pointers are
useful tools but can lead to nasty bugs or unreadable code quite easily.