DEV Community

Md Shahjalal
Md Shahjalal

Posted on

What Are Pointers in Go? A Simple Guide for Beginners

đź§  What Are Pointers in Go? A Simple Guide for Beginners

Confused about pointers in Go? You're not alone. In this post, we’ll break down what pointers are, why they matter, and how to use them — all with simple analogies and real code examples.


🔤 What Is a Pointer?

At its core, a pointer is just a memory address.

Think of your computer’s memory like a giant apartment building, where each apartment (memory location) has a unique number (address). When you create a variable in Go, it gets stored in one of these "apartments."

A pointer doesn’t store the value itself — it stores which apartment (address) the value lives in.

âś… A pointer is a variable that holds the memory address of another variable.


🏠 Real-World Analogy

Imagine you have a friend named Alice who lives at:

123 Memory Lane

You don’t carry her house around with you — you just write down her address.

Now, if someone asks you where Alice is, you can say:

“She lives at 123 Memory Lane.”

In programming:

  • The house = a variable (e.g., num := 10)
  • The address = a pointer (e.g., &num)
  • Going to the house and changing something inside = dereferencing the pointer

This is exactly how pointers work!


⚙️ The Two Key Symbols: & and *

There are only two symbols you need to understand:

Symbol Name Meaning
& Ampersand "Address of" → gives you the memory address
* Asterisk "Value at" → accesses the data at that address

Let’s see them in action.

package main

import "fmt"

func main() {
    num := 42
    fmt.Println("Value:", num)       // 42
    fmt.Println("Address:", &num)    // e.g., 0xc00001a0b8
}
Enter fullscreen mode Exit fullscreen mode

Output:

Value: 42
Address: 0xc00001a0b8
Enter fullscreen mode Exit fullscreen mode

Here, &num gives us the address where 42 is stored.

Now let’s store that address in a pointer:

var ptr *int = &num
fmt.Println("Pointer:", ptr)        // 0xc00001a0b8
fmt.Println("Value at ptr:", *ptr)  // 42
Enter fullscreen mode Exit fullscreen mode
  • ptr holds the address.
  • *ptr means: “go to that address and get the value.”

We call *ptr dereferencing the pointer.


âť“ Why Do We Need Pointers?

Go passes arguments to functions by value, which means it makes a copy of the data.

This leads to a big problem...

🟡 Problem: Can’t Modify Variables in Functions

func changeValue(x int) {
    x = 100
}

func main() {
    num := 1
    changeValue(num)
    fmt.Println(num) // Still prints 1 → Not changed!
}
Enter fullscreen mode Exit fullscreen mode

Why? Because changeValue only modifies its copy of num, not the original.


âś… Solution: Use a Pointer

Instead of passing the value, pass the address of the variable.

func changeValueWithPointer(x *int) {
    *x = 100 // Modify the original value
}

func main() {
    num := 1
    changeValueWithPointer(&num) // Pass the address
    fmt.Println(num) // Now prints 100 âś…
}
Enter fullscreen mode Exit fullscreen mode

Now it works! The function uses the pointer to modify the original variable.


🛠️ How to Declare and Use Pointers

1. Declare a Pointer

var ptr *int
Enter fullscreen mode Exit fullscreen mode
  • This creates a pointer to an integer (but it’s nil for now).

2. Assign an Address

num := 25
ptr = &num
Enter fullscreen mode Exit fullscreen mode

3. Dereference to Read or Write

fmt.Println(*ptr) // Read: prints 25
*ptr = 50         // Write: changes num to 50
Enter fullscreen mode Exit fullscreen mode

đź’ˇ When Should You Use Pointers?

Use Case Why
Modify variables in functions Pass a pointer to change the original
Avoid copying large structs Passing a pointer (8 bytes) is faster than copying KBs of data
Share data between functions Multiple parts of your program can access the same data
Working with slices, maps, channels These types are reference-like, but understanding pointers helps you debug and design better

⚠️ Common Pitfall: Nil Pointer Dereference

Never dereference a nil pointer — it will crash your program!

var p *int
fmt.Println(*p) // đź’Ą PANIC: invalid memory address
Enter fullscreen mode Exit fullscreen mode

Always make sure your pointer points to valid memory before using *p.


đź§Ş Example: Swapping Two Numbers

Here’s a classic use case: swap two numbers using pointers.

func swap(a, b *int) {
    *a, *b = *b, *a // Dereference and swap
}

func main() {
    x, y := 5, 10
    fmt.Println("Before:", x, y) // 5 10
    swap(&x, &y)
    fmt.Println("After:", x, y)  // 10 5
}
Enter fullscreen mode Exit fullscreen mode

Without pointers, this would be impossible in Go!


đź§  Summary: Key Takeaways

  • A pointer holds the memory address of a variable.
  • Use & to get the address: &num
  • Use * to access the value: *ptr
  • Pointers let functions modify original variables
  • They help avoid expensive copies and enable shared state
  • Be careful: don’t dereference nil pointers

📚 Final Thought

Pointers may seem scary at first, but once you think of them as addresses to data, they become much simpler.

They are one of Go’s most powerful features — and once you master them, you’ll write more efficient, flexible, and expressive code.

🔗 Remember: A pointer doesn’t hold the treasure. It holds the map to the treasure.


🙋‍♂️ Got Questions?

Leave a comment below!


*Enjoyed this post? Share it to your friends and follower!


Happy coding! đź’»

Top comments (1)

Collapse
 
js402 profile image
Alexander Ertli

Fantastic guide! You've done an excellent job of demystifying pointers for newcomers. The treasure map analogy is one of the best I've seen.

Building on your excellent point about pass-by-value, here's a more advanced detail on how slices and maps fit into this model.

They are essentially small structs that contain a pointer to the underlying data. This small struct gets passed by value, but the pointer inside it still allows the function to modify the original data.

This explains the common "gotcha" moment for new developers: when a function alters a map or slice's contents, which can be surprising if you expect pass-by-value to prevent any mutation of the original variable.

Awesome work on this valuable resource!