Pointers: & and *
What you'll learn:
- explain what a variable's address and a pointer are;
- read and change a variable through a pointer with
&and*; - pass a pointer to a function so it can change your variable;
- tell a
nilpointer from a pointer to zero, and create variables withnew.

A computer's memory is like a long street of identical cells. Every cell has a number—its address. When you write x := 1, Go picks a cell, puts 1 in it and remembers that the name x means exactly that cell.
Picture a street of identical houses and a slip of paper with the address of one of them. The house is the variable, with a value inside. The slip is the address: it takes you to the house, so you can look inside or change something there. You can hand the slip to someone else, and they will come to the very same house.
Why would you need the slip when you already have the name x? Let's see what plain assignment does:
package main
import "fmt"
func main() {
x := 1
y := x
y = 5
fmt.Println(x, y) // 1 5
}Let's walk through the example line by line:
x := 1builds the housexand puts1in it.y := xdoes not give the same house a second name. It builds a new houseyand copies the value into it.y = 5changes only the housey.fmt.Println(x, y)prints1 5: writing toyleftxalone.
Sometimes you need the opposite: a second way to reach the variable x itself. That is what pointers are for.
The address and the *int type
The & operator in front of a variable's name returns its address—that slip of paper. A pointer is a value that holds the address of a variable. A pointer to an int has the type *int:
x := 1
p := &x
fmt.Println(p == &x) // trueLet's go line by line:
x := 1is an ordinary variable.p := &xputs the address ofxintop.phas the type*int: "an address where anintlives".fmt.Println(p == &x)printstrue:pholds the same address that&xreturns.
What else matters about the pointer type:
- a pointer to
intcan hold only the address of anintvariable, never the address of a string; - the address itself is a number that changes from run to run, so programs almost never print it.
A pointer is a variable like any other: it has a name, a type and a value. After q := p you have two slips with the same address, and writing through q changes the same x.
Reading and writing through *p
The * operator in front of a pointer means "go to the address and take the variable itself". This is called dereferencing. Let's walk through an example line by line:
x := 1
p := &x
*p = 5
fmt.Println(x) // 5
y := *p
x = 7
fmt.Println(y, *p) // 5 7x := 1builds the housexand puts1in it.p := &xwrites the address of that house on the slipp.*p = 5follows the address inpand puts5intoxitself.fmt.Println(x)prints5.y := *pcopies whateverxholds at that moment into a new variabley.x = 7changesx, whileylives on its own: it still holds5.fmt.Println(y, *p)prints5 7:*pgoes toxafresh every time, so it sees7.
The diagram shows the moment right after the line *p = 5.
*p follows the address and takes x itself. The address is made up: in a real program it changes from run to run.
A slip can be rewritten
Here the slip-of-paper picture needs one caveat: a slip can be rewritten. After p = &y, the same p points to y, and *p = 0 changes y, not x. The house x is still there—the slip now leads to a different house.
Common mistake
The value was written into the pointer itself, without *:
x := 1
p := &x
p = 5 // ✗
fmt.Println(x, *p)cannot use 5 (untyped int constant) as *int value in assignmentThe program does not compile: p has the type *int, so it can hold only the address of an int variable, not a number. It is like writing "5" on the slip where the address should be. To store 5 in the variable p points to, write *p = 5.
Key points
- A pointer holds a variable's address;
&xtakes the address, and a pointer tointhas the type*int. *pis the variable at that address: you read and write through it.y := *pcopies the value at that moment, while*preads the variable afresh every time.- A pointer gets an address (
p = &y); a value goes in through*p = 5.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.