Go Pointers
A pointer stores the memory address of another variable rather than a value directly. Pointers allow functions to modify the original data they point to and help avoid expensive copies of large data structures.
Understanding Memory Addresses
x := 42
Memory:
┌──────────────────────────┐
│ Address: 0xc0000b4010 │
│ Variable: x │
│ Value: 42 │
└──────────────────────────┘
A pointer stores the address: 0xc0000b4010
Declaring and Using a Pointer
Use & to get the address of a variable. Use * to read or change the value at that address.
package main
import "fmt"
func main() {
x := 42
p := &x // p is a pointer to x
fmt.Println(x) // 42 — the value
fmt.Println(&x) // 0x... — the address of x
fmt.Println(p) // 0x... — same address stored in p
fmt.Println(*p) // 42 — the value at the address (dereference)
*p = 100 // change x through the pointer
fmt.Println(x) // 100
}
Pointer Operators
| Operator | Name | What It Does |
|---|---|---|
& | Address-of | Gets the memory address of a variable |
* | Dereference | Reads or writes the value at an address |
Pointers in Functions
Without a pointer, a function receives a copy of the value. Changes inside the function do not affect the original.
package main
import "fmt"
// Without pointer – changes do NOT affect original
func doubleByValue(n int) {
n = n * 2
}
// With pointer – changes DO affect original
func doubleByPointer(n *int) {
*n = *n * 2
}
func main() {
a := 10
doubleByValue(a)
fmt.Println(a) // 10 — unchanged
b := 10
doubleByPointer(&b)
fmt.Println(b) // 20 — changed
}
Pointer to a Struct
Passing a pointer to a struct lets a function modify the struct's fields directly. Go also allows accessing fields through a pointer without explicit dereferencing.
package main
import "fmt"
type Person struct {
Name string
Age int
}
func birthday(p *Person) {
p.Age++ // Go automatically dereferences — same as (*p).Age++
}
func main() {
alice := Person{Name: "Alice", Age: 29}
birthday(&alice)
fmt.Println(alice.Age) // 30
}
new() Function
The new function allocates memory for a type, sets it to zero, and returns a pointer to it.
package main
import "fmt"
func main() {
p := new(int) // p is *int, pointing to value 0
*p = 55
fmt.Println(*p) // 55
}
Nil Pointer
A pointer with no address assigned has the value nil. Dereferencing a nil pointer causes a panic.
package main
import "fmt"
func main() {
var p *int
fmt.Println(p) //
if p != nil {
fmt.Println(*p)
} else {
fmt.Println("pointer is nil — cannot dereference")
}
}
When to Use Pointers
| Situation | Use Pointer? |
|---|---|
| Function needs to modify the caller's variable | Yes |
| Large struct — avoid copying | Yes |
| Small value, read-only use | No — pass by value |
| Representing optional/absent value | Yes — nil pointer means absent |
Key Points
- A pointer stores the memory address of another variable
&xgets the address of x;*preads or writes the value at address p- Functions with pointer parameters can modify the original variable
- Go automatically dereferences struct pointers when accessing fields
- Always check for nil before dereferencing to avoid panics
