Why Pointers Are Your Best Friends in Go!
Let’s face it — pointers in Go sometimes get a bad rap. They sound fancy, they look intimidating, and some devs tend to avoid them like the plague. But guess what? They’re not just some geeky concept for brainy coders — they’re super useful in production-ready code, and here’s why you should start loving them.

Redundant Memory Allocations are a thing of the past
Let’s break it down with an example. Imagine you’re working with a list of user details, and you want to apply some updates. Without pointers, you’ll be creating extra copies of the data, wasting memory, and creating unnecessary overhead.
With Pointers:
package main
import (
"encoding/json"
"fmt"
)
type PlatformDetail struct {
Name string
Age string
}
var Platforms []*PlatformDetail
func main() {
name := "sayak"
age := "26"
PlatformDetail_1 := PlatformDetail{
Name: name,
Age: age,
}
name = "shashank"
age = "25"
PlatformDetail_2 := PlatformDetail{
Name: name,
Age: age,
}
Platforms = append(Platforms, &PlatformDetail_1)
Platforms = append(Platforms, &PlatformDetail_2)
dd, _ := json.Marshal(Platforms)
fmt.Println(string(dd))
for _, j := range Platforms {
j.Name = "Dr. " + j.Name // Updating in-place
}
dd, _ = json.Marshal(Platforms)
fmt.Println(string(dd))
}
Output:
[{"Name":"sayak","Age":"26"},{"Name":"shashank","Age":"25"}]
[{"Name":"Dr. sayak","Age":"26"},{"Name":"Dr. shashank","Age":"25"}]
Why It’s Cool:
Using pointers avoids creating unnecessary arrays and copying data.
Without Pointers:
package main
import (
"encoding/json"
"fmt"
)
func main() {
type PlatformDetail struct {
Name string
Age string
}
var Platforms []PlatformDetail
name := "sayak"
age := "26"
PlatformDetail_1 := PlatformDetail{
Name: name,
Age: age,
}
name = "shashank"
age = "25"
PlatformDetail_2 := PlatformDetail{
Name: name,
Age: age,
}
Platforms = append(Platforms, PlatformDetail_1)
Platforms = append(Platforms, PlatformDetail_2)
dd, _ := json.Marshal(Platforms)
fmt.Println(string(dd))
var pArr []PlatformDetail
for _, j := range Platforms {
j.Name = "Dr. " + j.Name // Creating copies
pArr = append(pArr, j)
}
dd, _ := json.Marshal(pArr)
fmt.Println(string(dd))
}
Output:
[{"Name":"sayak","Age":"26"},{"Name":"shashank","Age":"25"}]
[{"Name":"Dr. sayak","Age":"26"},{"Name":"Dr. shashank","Age":"25"}]
Why It’s Not Cool:
You’re basically copying and pasting the same data twice. Wasteful! Pointers let you work directly with the original data structure, no double work needed.
Null vs Empty Fields
Let’s say you’re dealing with some JSON fields, and you want to differentiate between a null
field and an empty one. With pointers, you can handle this distinction elegantly.
Example:
package main
import (
"encoding/json"
"fmt"
)
type User struct {
Name *string `json:"name,omitempty"`
Age *int `json:"age,omitempty"`
}
func main() {
name := "John"
age := 30
user1 := User{
Name: &name, // Pointer holds a value
Age: nil, // Explicit null
}
user2 := User{
Name: nil, // Explicit null
Age: &age, // Pointer holds a value
}
u1, _ := json.Marshal(user1)
u2, _ := json.Marshal(user2)
fmt.Println("User 1:", string(u1)) // {"name":"Shashank"}
fmt.Println("User 2:", string(u2)) // {"age":25}
}
Why It’s Useful:
Pointers make it crystal clear whether a field is intentionally null or just empty. This is super handy when dealing with APIs or any system that cares about whether something exists or doesn’t.
Final Thoughts: Pointers Are Your New BFFs

Sure, pointers might seem a bit intimidating at first, but trust me — they’ll become your secret weapon in writing clean, efficient, and production-ready code. Whether it’s avoiding unnecessary memory allocations or distinguishing between null and empty values, pointers just make things better.
Next time you’re wondering, “Should I use pointers?”, just remember: pointers = power!