Pointers

Go has pointers, borrowed straight from C in spirit — an address-of operator, a dereference operator, the works. What Go leaves out, on purpose, is pointer arithmetic: you can't add 1 to a pointer and walk through memory the way you can in C.

& and *

Go main.go
package main

import "fmt"

func main() {
	age := 30
	p := &age

	fmt.Println(*p)
	*p = 31
	fmt.Println(age)
}
Output
30
31

&age takes the memory address of age and stores it in p, a variable of type *int ("pointer to int"). *p dereferences the pointer — reading or writing through it reaches age itself, so *p = 31 changes age even though the assignment doesn't mention age by name.

Why functions need pointers

Go passes arguments by value by default — a function gets its own copy. A pointer parameter is how a function reaches back and modifies the caller's actual variable:

Go main.go
package main

import "fmt"

func double(n int) {
	n = n * 2
}

func doublePtr(n *int) {
	*n = *n * 2
}

func main() {
	a := 10
	double(a)
	fmt.Println("After double:", a)

	doublePtr(&a)
	fmt.Println("After doublePtr:", a)
}
Output
After double: 10
After doublePtr: 20

double(a) only ever changes its own local copy of n, so a is untouched. doublePtr(&a) receives a's address and dereferences it to modify the original — this is exactly the mechanism behind the pointer-receiver methods from the previous lesson.

Note: Go has no pointer arithmetic — you cannot write p + 1 to move a pointer forward through memory like you can in C. This closes off an entire category of memory-corruption bugs C code is prone to, at the cost of the low-level control C gives you. Go also has automatic garbage collection, so unlike C's malloc/free, there's no manual step to free memory a pointer refers to once nothing points to it anymore.