Pointers in Go are variables that store memory addresses of other variables. They provide a way to directly manipulate memory and pass references to values across functions.
Basic Pointer Operations
The address operator (&) obtains the memory address of a variable, while the dereference operator (*) accesses the value stored at that address.
package main
import "fmt"
func main() {
// Declare an integer variable
value := 42
fmt.Println(value, &value) // 42 0xc0000a6058
// Assign the memory address to another variable
addr := &value
fmt.Println(addr, &addr, *addr) // 0xc0000a6058 0xc0000ca020 42
// Modify the value through the pointer
*addr = 99
fmt.Println(value, &value) // 99 0xc0000a6058
// Declare a pointer variable explicitly
var ptr *int
ptr = &value
*ptr = 88 // Assign through pointer
fmt.Println(value) // 88
}
Mulitlevel Pointers
Go supports pointers to pointers, allowing multiple levels of indirection:
func main() {
num := 15
p1 := &num
// Pointer to pointer
var p2 **int
p2 = &p1
fmt.Printf("p2 stores address of p1: %p\n", p2)
fmt.Printf("p2 points to value: %d\n", *p2)
fmt.Printf("p2 own address: %p\n", &p2)
fmt.Printf("p2 dereferences to num: %d\n", **p2)
}
Array Poinetrs and Pointer Arrays
Array Pointers
An array pointer is a pointer that references an entire array:
func main() {
data := [3]int{10, 20, 30}
fmt.Printf("data address: %p\n", &data)
// Define pointer to the array
var arrPtr *[3]int
arrPtr = &data
fmt.Printf("arrPtr -> data: %p\n", arrPtr)
fmt.Printf("arrPtr value: %d\n", *arrPtr)
fmt.Printf("arrPtr own address: %p\n", &arrPtr)
// Modify elements through pointer
(*arrPtr)[0] = 100
arrPtr[1] = 200 // Simplified syntax
fmt.Printf("arrPtr value: %d\n", *arrPtr)
}
Pointer Arrays
A pointer array stores pointers as its elements:
func main() {
x, y, z := 5, 15, 25
// Array of pointers
ptrArray := [3]*int{&x, &y, &z}
fmt.Println(ptrArray) // [0xc00001c0a8 0xc00001c0d0 0xc00001c0d8]
fmt.Println(*ptrArray[0]) // 5
*ptrArray[0] = 50
fmt.Println(*ptrArray[0]) // 50
}
Functions Returning Pointers
Functions can return pointers, providing a way to return memory addresses from functions:
func createArray() *[3]int {
arr := [3]int{1, 2, 3}
return &arr
}
func main() {
result := createArray()
fmt.Println(*result) // [1 2 3]
}
Pointers as Function Parameters
Passing pointers to functions allows direct modification of the original value:
func updateValue(ptr *int) {
fmt.Println("Received pointer:", ptr)
fmt.Println("Dereferenced value:", *ptr)
*ptr = 500
}
func main() {
num := 250
updateValue(&num)
fmt.Println(num) // 500
}