Passing by Reference in Go: A Practical Guide
Daniel Hayes
Full-Stack Engineer · Leapcell

Key Takeaways
- Go uses pass-by-value semantics, but pointers enable reference-like behavior.
- Use pointers when you need to modify the original value.
- Structs and large data types benefit from pointer usage for performance.
Go (Golang) is a statically typed, compiled programming language known for its simplicity and performance. One concept that often confuses newcomers is how Go handles function arguments—especially when it comes to passing data by reference.
In this article, we’ll explore what "pass by reference" means in Go, how it works, and how you can use it effectively to write cleaner, more efficient code.
Understanding Go’s Parameter Passing Semantics
Go uses pass-by-value semantics for function arguments. This means that when you pass a variable to a function, Go makes a copy of that value. However, when you pass a pointer (i.e., the memory address of a value), you can achieve the effect of passing by reference.
Let’s look at a basic example:
package main import "fmt" func modify(x int) { x = 10 } func main() { a := 5 modify(a) fmt.Println(a) // Output: 5 }
Here, modify
receives a copy of a
, so any changes inside modify
won’t affect the original value.
Achieving "Pass by Reference" with Pointers
To actually modify the original variable inside the function, you must pass a pointer to that variable:
package main import "fmt" func modify(x *int) { *x = 10 } func main() { a := 5 modify(&a) fmt.Println(a) // Output: 10 }
Explanation:
x *int
: Declares thatmodify
accepts a pointer to anint
.&a
: The&
operator gets the address ofa
.*x = 10
: The*
operator dereferences the pointer, allowing you to change the original value.
When to Use Pointers in Go
You should use pointers when:
- You want to modify the original value passed to a function.
- You want to avoid copying large structs or slices for performance.
- You’re working with shared state (e.g., data structures or objects being modified across multiple functions).
Here’s an example using a struct:
type User struct { Name string Age int } func updateName(u *User) { u.Name = "Alice" } func main() { user := User{Name: "Bob", Age: 30} updateName(&user) fmt.Println(user.Name) // Output: Alice }
Common Pitfalls
-
Forgetting to pass the pointer:
updateName(user) // Error: cannot use user (type User) as type *User
-
Modifying values inside slices and maps: Go passes slices and maps by value, but they contain references to underlying data. So in many cases, you can modify their contents without using pointers. Be mindful of this behavior.
Conclusion
While Go does not support traditional pass-by-reference like some other languages, it gives you full control through the use of pointers. Understanding how and when to use pointers allows you to write more efficient and expressive Go code.
If you come from a language like C, C++, or Python, knowing this idiom will make you more comfortable when dealing with memory and performance-sensitive applications in Go.
FAQs
No, Go only supports pass-by-value, but you can simulate reference semantics using pointers.
When you want to modify the original value or avoid copying large data structures.
Yes, because slices and maps contain internal references to underlying data.
We are Leapcell, your top choice for hosting Go projects.
Leapcell is the Next-Gen Serverless Platform for Web Hosting, Async Tasks, and Redis:
Multi-Language Support
- Develop with Node.js, Python, Go, or Rust.
Deploy unlimited projects for free
- pay only for usage — no requests, no charges.
Unbeatable Cost Efficiency
- Pay-as-you-go with no idle charges.
- Example: $25 supports 6.94M requests at a 60ms average response time.
Streamlined Developer Experience
- Intuitive UI for effortless setup.
- Fully automated CI/CD pipelines and GitOps integration.
- Real-time metrics and logging for actionable insights.
Effortless Scalability and High Performance
- Auto-scaling to handle high concurrency with ease.
- Zero operational overhead — just focus on building.
Explore more in the Documentation!
Follow us on X: @LeapcellHQ