Pointer vs Value in Go: Key Differences and When to Use Each
value holds the actual data, while a pointer holds the memory address of that data. Using pointers allows you to modify the original data and save memory by avoiding copies, whereas values work with independent copies.Quick Comparison
This table summarizes the main differences between pointers and values in Go.
| Aspect | Value | Pointer |
|---|---|---|
| Data stored | Actual data | Memory address of data |
| Memory usage | Copies data, uses more memory | Stores address, uses less memory |
| Modification effect | Changes affect only the copy | Changes affect original data |
| Default zero value | Zero value of the type (e.g., 0, "", false) | nil (no address) |
| Syntax | Direct variable usage | Use * to dereference, & to get address |
| Use case | When data copy is cheap or isolation needed | When sharing or modifying original data |
Key Differences
Values in Go hold the actual data. When you assign or pass a value, Go copies the entire data. This means changes to the copy do not affect the original variable. This is simple and safe but can be inefficient for large data.
Pointers hold the memory address where the data lives. Instead of copying data, pointers let you work with the original data directly. You can change the original data through a pointer, which is useful for efficiency and when you want to share data between functions.
Using pointers requires understanding how to get the address with & and access the data with *. Values are easier to use but less flexible for certain tasks like modifying shared data or saving memory.
Code Comparison
This example shows how to update a number using a value copy. The original number does not change.
package main import "fmt" func updateValue(num int) { num = num + 10 fmt.Println("Inside updateValue:", num) } func main() { number := 5 updateValue(number) fmt.Println("After updateValue call:", number) }
Pointer Equivalent
This example shows how to update a number using a pointer. The original number changes because the function works with its address.
package main import "fmt" func updatePointer(num *int) { *num = *num + 10 fmt.Println("Inside updatePointer:", *num) } func main() { number := 5 updatePointer(&number) fmt.Println("After updatePointer call:", number) }
When to Use Which
Choose values when you want simple code and your data is small or you want to avoid side effects. Values are great for independent copies and safer concurrency.
Choose pointers when you need to modify the original data, avoid copying large structs or arrays, or share data efficiently between functions. Pointers give you control and better performance for big data.