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 *
package main import "fmt" func main() { age := 30 p := &age fmt.Println(*p) *p = 31 fmt.Println(age) }
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:
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) }
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.
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.