Introduction to Pointers
Pointers are variables that store memory addresses of other variables. They allow you to pass references to values instead of copies, enabling efficient memory usage and the ability to modify values across function boundaries. In Go, pointers are denoted with the* symbol for types and the & operator to get an address.
Basic Pointer Syntax
Key Pointer Operations
| Operation | Syntax | Description |
|---|---|---|
| Address-of | &variable | Gets the memory address of a variable |
| Dereference | *pointer | Accesses the value at the pointer’s address |
| Pointer type | *Type | Declares a pointer type |
Pointers vs Values
Understanding when values are copied vs when they’re referenced is crucial for writing efficient Go code.When you pass a pointer to a function, the pointer itself is copied, but it still points to the same memory location. This allows the function to modify the original value.
Pointers with Composite Types
Different composite types in Go have different behaviors regarding pointers and copying.Arrays
Arrays are always copied when passed to functions. Use pointers to avoid copying large arrays.Arrays and Pointers
Slices
Slices already contain a pointer to their underlying array, so they behave differently.Slices and Pointers
Maps
Maps are reference types, so they don’t need pointers to be modified in functions.Maps Don't Need Pointers
Structs
Structs are value types and are copied when passed to functions.Structs and Pointers
Practical Example: Log Parser
Here’s a real-world example showing why pointers matter for maintaining state:In this example,
parse and update use pointer receivers because they need to modify the parser’s state. The summarize function uses a value receiver because it only reads the data.Best Practices
When to Use Pointers
When to Use Pointers
Use pointers when:
- You need to modify the original value
- The value is large and copying would be expensive
- You want to indicate that a parameter is optional (can be
nil) - You’re implementing methods that modify the receiver
- The value is small (a few words)
- The type is a map, slice, or channel (already reference types)
- You want to ensure immutability
Pointer Safety
Pointer Safety
- Always check for
nilbefore dereferencing - Don’t return pointers to local variables (they’ll be moved to heap)
- Be careful with pointer arithmetic (not allowed in Go)
- Remember that pointer equality checks the address, not the value
Performance Considerations
Performance Considerations
- Passing large structs by pointer avoids copying overhead
- However, pointers can reduce cache locality
- Modern CPUs optimize for value types in many cases
- Profile before optimizing with pointers
Common Patterns
Optional Parameters with Nil Pointers
Optional Values
Pointer to Interface
Pointer to Interface
Related Topics
Methods and Receivers
Learn about pointer vs value receivers
Structs
Understanding struct memory layout
Slices
How slices use pointers internally
Interfaces
Interfaces and pointer receivers