Go by Example: Pointers
Pointers hold the memory address of a value. This example covers pointer declaration, dereferencing, the nil value, and how pointers interact with structs and functions.
Code
package main
import "fmt"
func main() {
// 1. Basic Pointer Declaration
// & generates a pointer to its operand.
i := 42
p := &i // point to i
fmt.Println(*p) // read i through the pointer
*p = 21 // set i through the pointer
fmt.Println(i) // see the new value of i
// 2. Nil Pointers
// The zero value for a pointer is nil.
var ptr *int
fmt.Println("Uninitialized pointer:", ptr)
// 3. Pointers to Structs
type Vertex struct {
X, Y int
}
v := Vertex{1, 2}
vp := &v
vp.X = 1e9 // Struct fields can be accessed through the pointer
fmt.Println(v)
// 4. New Function
// new(T) allocates memory for a T, zeroes it, and returns *T.
np := new(Vertex)
fmt.Println(np)
}
Explanation
Pointers in Go are a fundamental primitive that store the memory address of a value rather than the value itself, enabling efficient data manipulation and sharing across function boundaries without the performance cost of copying large data structures. By utilizing the & (address-of) and * (dereference) operators, developers can directly access and modify the underlying memory location of a variable, a capability that is essential for implementing complex data structures like linked lists, trees, and graphs where nodes must reference one another. Unlike C or C++, Go pointers are safe; the language prohibits pointer arithmetic by default to prevent common classes of memory safety errors, such as buffer overflows or accessing invalid memory regions, while still retaining the power of reference semantics.
The concept of nil pointers is integral to Go's type system, representing a pointer that does not currently reference any valid memory address; attempting to dereference a nil pointer results in a runtime panic, necessitating careful checks in code where pointer validity is not guaranteed. Furthermore, Go's escape analysis compiler optimization automatically determines whether a variable's memory should be allocated on the stack or the heap based on its scope and usage, effectively abstracting manual memory management while ensuring that pointers remain valid even after the function that created them returns.
- Address-of (&): Gets the memory address.
- Dereference (*): Accesses the value at the address.
- No Arithmetic: You cannot do
p++like in C. - Pass by Reference: Use pointers to modify function arguments.

