tezvyn:

Go Pointers: Memory Addresses, Not Math

AI-drafted, machine-checkedSource: go.devintermediate

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.

Read the original → go.dev

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.