Go Pointers in Depth
A pointer is a value that holds the address of another value. The address is the place in memory where that value sits.
new makes a pointer to a zero value
new(int) returns a pointer to a fresh int. The int starts at the zero value, and a write through the pointer changes it.
package main
import "fmt"
func main() {
p := new(int)
fmt.Println(*p)
*p = 42
fmt.Println(*p)
}Field access through a struct pointer
The pointer holds a Point value built with the & sign. A field reads and writes through the pointer with a dot, with no arrow.
package main
import "fmt"
type Point struct {
X int
Y int
}
func main() {
p := &Point{X: 3, Y: 4}
fmt.Println(p.X, p.Y)
p.X = 10
fmt.Println(p.X)
}A function can return a pointer to its local
makeScore builds a local value and returns its address. The value still reads after the function ends.
package main
import "fmt"
func makeScore() *int {
s := 90
return &s
}
func main() {
p := makeScore()
fmt.Println(*p)
}A nil guard before reading through two pointers
A pointer with no target holds nil. The guard checks both pointers before the double star reads the number.
package main
import "fmt"
func main() {
var p *int
fmt.Println(p == nil)
x := 7
q := &x
r := &q
if r != nil && *r != nil {
fmt.Println(**r)
}
}Example
package main
import "fmt"
type Node struct {
Value int
Next *Node
}
func main() {
second := &Node{Value: 2}
first := &Node{Value: 1, Next: second}
fmt.Println(first.Value)
fmt.Println(first.Next.Value)
}Key points
- Use new with a type to make a pointer to a fresh zero value.
- The star in *p reads the value a pointer points at.
- Writing through *p changes the value at the address.
- A field of a struct reads through a pointer with the same dot shape as a value.
- A nil pointer holds no address and must not be read through.
- A pointer can point at another pointer, and two stars read through both.
In this example, the second node holds the value 2 and no next node. The first node holds the value 1 and points at the second node. The first print line reads the value of the first node. The second line follows the Next pointer and reads the value 2.
Note
Go pointers support no arithmetic, so a pointer never steps to a nearby address.
Try it Yourself
Edit the code, then press Run.
Running is simulated ยท Go Playground
Exercise
What does *p hold right after the line p := new(int)?