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 thataandbpoint todouble(x *int)--- doubles the value thatxpoints to