Go Pointers Explained: A Beginner’s Guide to & and *

In Go, pointers are an essential concept. While you may not use them every day, they become extremely useful when you need to modify external variables, improve performance, or work with large structs. In this article, we’ll explore how the &
and *
operators work with simple, practical examples.
The Basics
🔗&
(address-of operator): gets the memory address of a variable.*
(dereference operator): retrieves the value stored at a given memory address.
gopackage main
import "fmt"
func main() {
x := 10
p := &x // &x gets the address of x, p is a *int pointer
fmt.Println("x =", x) // 10
fmt.Println("p =", p) // prints the memory address of x (e.g. 0xc000012090)
fmt.Println("*p =", *p) // dereference p to get the value of x → 10
*p = 20 // modify the value through the pointer
fmt.Println("x =", x) // 20, because *p changed x
}
Passing by Value vs Passing by Pointer
🔗By default, Go uses value passing for function arguments, meaning the function receives a copy of the variable. Any changes won’t affect the original. If you want a function to modify the actual variable, you need to pass a pointer.
gopackage main
import "fmt"
// Pass by value: does not change the original variable
func addOneByValue(n int) {
n = n + 1
}
// Pass by pointer: can modify the original variable
func addOneByPointer(n *int) {
*n = *n + 1
}
func main() {
a := 5
addOneByValue(a)
fmt.Println("after addOneByValue:", a) // 5, unchanged
addOneByPointer(&a)
fmt.Println("after addOneByPointer:", a) // 6, modified
}
Pointers with Structs
🔗When working with structs, passing by value creates a copy of the entire struct. This can be inefficient for large structs, and modifications won’t affect the original. By passing a pointer, you can update the struct directly.
gopackage main
import "fmt"
type User struct {
Name string
Age int
}
func updateUser(u *User) {
u.Age = u.Age + 1
}
func main() {
user := User{Name: "Alvin", Age: 30}
updateUser(&user)
fmt.Println(user) // {Alvin 31}
}
Key Takeaways
🔗&
: gets the address of a variable.*
: accesses or modifies the value at that address.
Use cases:
- Modify external variables inside functions.
- Avoid unnecessary memory copies when working with large structs.
- Build data structures (linked lists, trees, etc.) that rely on pointers.
Mastering &
and *
will give you a deeper understanding of Go’s memory model and allow you to write more efficient and powerful code.

Alvin
Software engineer, interested in financial knowledge, health concepts, psychology, independent travel, and system design.