Stage 1 · Code
Methods, Interfaces & Errors
Pointers
Understand memory addresses, learn when to pass by pointer instead of value, and write mutation-safe functions.
Address and Dereference
Every variable is stored at a memory address. The address-of operator & gives you that address. The dereference operator * reads the value at an address. Together they are the foundation of pointer semantics.
Pointer Types
A pointer type is written *T — a pointer to a value of type T. The zero value for any pointer type is nil, which means 'pointing at nothing'.
Mutation Through Pointers
When you pass a pointer to a function, the function can modify the original value. This is the only way to have a function change a caller's variable (other than returning the new value).
nil Pointers
A nil pointer does not point to any memory. Dereferencing a nil pointer (reading or writing through it) causes a runtime panic. Always check whether a pointer is nil before dereferencing it.
When to Use Pointers
Not every type needs a pointer. Go gives you a clear rule of thumb: use a pointer when you need mutation or when copying would be expensive or semantically wrong.
| Use pointer when | Use value when |
|---|---|
| Function must modify the caller's variable | Function only needs to read |
| Struct is large and copying is expensive | Struct is small (a few fields) |
| Shared ownership across goroutines | Single-owner, local use |
| Method must modify the receiver | Method only reads the receiver |
| Type has a nil state that represents 'absent' | Value is always present |
Slices and maps are already reference types — you do not need *[]T or *map[K]V to share them between functions. A *[]T is occasionally used when a function needs to append to a slice and have the caller see the new header, but this is uncommon. For most collection types, just pass the slice or map directly.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.