Go 4 min read

[Go Tutorials P4] Pointer

What is a Pointer?

In Go, a pointer is a variable that stores the memory address of another variable.

Instead of holding a value directly, a pointer points to a memory location where the value is stored.

Think of it like this:

  • Normal variable → value holder

  • Pointer → address holder that leads to the value

Declaring and Using Pointers

You declare a pointer by using the * symbol.

var p *int
  • p is now a pointer to an integer (int).

  • It holds the address of an integer, not the integer itself.

Getting the Address of a Variable

Use the & operator to get the address of a variable

x := 42
p := &x  // p points to x

Now:

  • p holds the address of x

  • *p gives you access to the value at that address

Dereferencing a Pointer

Use * again to dereference the pointer — meaning "go to the address and fetch the value."

fmt.Println(*p) // prints 42

You can also modify the value through the pointer:

*p = 100
fmt.Println(x) // prints 100

Because p points to x, changing *p also changes x!

Why Use Pointers?

There are several reasons why pointers are important:

Reason Explanation
Efficiency Avoid copying large data structures (e.g., structs).
Mutability Allow functions to modify passed-in variables.
Data Sharing Share and update common resources without duplication.

Pointers and Functions

Without pointers, Go functions get a copy of the argument:

func changeValue(val int) {
    val = 100
}

x := 10
changeValue(x)
fmt.Println(x)  // prints 10 (not changed!)

But with pointers:

func changeValue(p *int) {
    *p = 100
}

x := 10
changeValue(&x)
fmt.Println(x)  // prints 100 (changed!)

Now the function directly modifies the original value.

Pointers to Structs

Pointers are very common when working with structs in Go.

Example:

type Person struct {
    Name string
    Age  int
}

func birthday(p *Person) {
    p.Age += 1
}

Usage:

p := Person{Name: "Alice", Age: 30}
birthday(&p)
fmt.Println(p.Age) // prints 31

Even more interesting: when you have a pointer to a struct, Go automatically dereferences it for you when accessing fields:

var p = &Person{Name: "Bob", Age: 25}
fmt.Println(p.Name)  // Go reads (*p).Name automatically

Zero Value of a Pointer

When you declare a pointer without initializing it, its zero value is nil.

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

Trying to dereference a nil pointer causes a runtime panic. Always check or initialize before use!

Pointers vs Slices, Maps, Channels

In Go:

  • Slices, maps, and channels are reference types by design.

  • You don't need to use pointers to pass them around — they already behave like pointers!

func addElement(s []int) {
    s[0] = 99
}

arr := []int{1, 2, 3}
addElement(arr)
fmt.Println(arr) // [99 2 3]

No explicit * or & needed here!

Common Mistakes with Pointers

  • Dereferencing a nil pointer → runtime panic.

  • Forgetting to use & when passing to a function expecting a pointer.

  • Overusing pointers for small data types (e.g., int, bool) — sometimes passing by value is simpler and better!

A Quick Real-Life Analogy

Imagine variables as houses and pointers as house addresses:

  • A variable (x) is like your friend's house.

  • A pointer (p) is a piece of paper with their house address.

  • Dereferencing (*p) is you visiting the house to see (or modify) what's inside.

Final Words

Pointers may seem intimidating at first, but in Go, they are:

  • Simple,

  • Predictable,

  • Powerful.

Mastering pointers will help you write faster, more memory-efficient, and more idiomatic Go code.

Keep practicing, and pointers will become second nature!

📌 Quick Summary:

Concept Symbol Description
Get address & p := &x
Dereference * value := *p
Pointer to type *T pointer to a value of type T
Nil pointer nil uninitialized pointer