Step 1 of 7 · Reading · ~4 min
Learn
Pointers and Errors
Pointers
A pointer is a value that holds the address of another variable. Go keeps the idea deliberately small — no pointer arithmetic, no manual freeing — and you reach for it for one everyday reason: letting a function change a variable that lives outside it.
Two operators: & and *
&x takes the address of the variable x and gives you a pointer. *p goes the other
way — it dereferences the pointer, reading or writing the value stored at that address.
The type of "pointer to an int" is spelled *int.
The & is not new. fmt.Scan(&x) has been handing Scan an address since Variables and
Types, so it could write into your variable; that argument was a pointer all along.
Why functions need them
Go passes every argument by value, so a function works on a copy. A pointer parameter is how you opt out of that:
Two pointers, two writes, and a swap works the same way:
Now the trap that catches everyone once. Assigning to the parameter instead of through it compiles perfectly and does nothing:
a and b are themselves copies — copies of addresses. Rearranging them is invisible to the
caller. Only a write through the * reaches the original.
Addresses of slice elements
You can take the address of a variable or of a slice element:
Things you can take the address of are called addressable: variables, slice elements,
struct fields. A computed expression is not — &(a + b) does not compile. And remember from
Loops that the value in for _, v := range scores is a copy of the element, so &v is
the address of that copy, not of the slice.
nil pointers
The zero value of every pointer type is nil:
Dereferencing nil is a runtime panic, not a compile error, so check if r != nil whenever a
pointer might be missing. What Go leaves out compared with C: p + 1 is a compile error
(there is no pointer arithmetic), and there is nothing to call to release memory — the garbage
collector reclaims it once nothing points there.
Common mistakes
- Assigning to the parameter instead of through it. Like
brokenSwap, a mutator whose body isn = &otherrebinds only the function's own copy of the address. The caller's value never changes, so the program echoes its input back unchanged. - Pointing at a loop copy.
for _, v := range numshands you a fresh copy each pass; writes through&vland in that copy and are thrown away at the end of the iteration. Index the slice —&nums[i]— when you mean to touch the real element. - Printing inside the mutator. A function that takes a
*intto modify it should modify it and nothing else. If it prints too, every value shows up twice in the output. - Treating the pointer as a number.
n++orn = n + 1wherenis a*intis a compile error: a pointer is not arithmetic in Go, and the++belongs somewhere else.
Your exercise
Fill in increment so the int its argument points at ends up one larger. The starter already
parses the input, calls increment once per number with that element's address, and prints the
results — only the function body is missing. The likeliest mistake is writing to the parameter
rather than through it: it compiles, and your output is the input unchanged.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…