Lesson 10 of 18

Pointers

Understanding Pointers

A pointer holds the memory address of a value. Instead of passing data around by copying it, you can pass a pointer to the original data.

Pointer Types and Operators

The type *T is a pointer to a value of type T. The & operator takes the address of a variable. The * operator dereferences a pointer, giving you the value it points to:

x := 42
p := &x         // p is *int, points to x
fmt.Println(*p)  // 42 (read through the pointer)
*p = 100         // modify x through the pointer
fmt.Println(x)   // 100

Think of pointers like the Enterprise's targeting sensors: they do not hold the enemy ship, they lock onto its coordinates. The & operator gets the coordinates; * fires on them.

Zero Value

The zero value of a pointer is nil. A nil pointer does not point to anything. Dereferencing a nil pointer causes a runtime panic:

var p *int       // p is nil
fmt.Println(p)   // <nil>

Passing by Value vs Pointer

Go is pass-by-value. When you pass a variable to a function, the function gets a copy. To let a function modify the original, pass a pointer:

func increment(x *int) {
    *x++
}

n := 5
increment(&n)
fmt.Println(n) // 6

Without the pointer, increment would modify a copy and n would stay 5.

When to Use Pointers

Use pointers when you need to:

  • Modify the caller's data --- the most common reason
  • Avoid copying large structs --- passing a pointer is cheaper than copying a large value
  • Signal absence --- a nil pointer can mean "no value"

The new function allocates memory and returns a pointer to the zero value:

p := new(int)    // *int pointing to 0
*p = 42

Your Task

Write two functions:

  • swap(a, b *int) --- swaps the values that a and b point to
  • double(x *int) --- doubles the value that x points to
Go runtime loading...
Loading...
Click "Run" to execute your code.