0
0
GoComparisonBeginner · 4 min read

Value Receiver vs Pointer Receiver in Go: Key Differences and Usage

In Go, a value receiver gets a copy of the data, so changes inside the method don't affect the original value. A pointer receiver gets the address of the data, allowing the method to modify the original value directly.
⚖️

Quick Comparison

Here is a quick side-by-side comparison of value receivers and pointer receivers in Go.

AspectValue ReceiverPointer Receiver
Data AccessWorks on a copy of the valueWorks on the original value via its address
Modification EffectChanges do NOT affect the originalChanges affect the original value
Memory UseCopies data, can be costly for large structsNo copy, more efficient for large structs
Method CallCan be called on both value and pointerCan be called on both pointer and value (if addressable)
Use CaseFor small, immutable dataFor large data or when mutation is needed
⚖️

Key Differences

A value receiver means the method operates on a copy of the struct. This means any changes made inside the method do not affect the original struct outside the method. It is like making a photocopy of a document and writing on the copy; the original stays the same.

On the other hand, a pointer receiver means the method receives the memory address of the struct. This allows the method to modify the original struct directly. It is like having the original document and writing on it, so the changes are visible everywhere.

Using pointer receivers is more efficient for large structs because it avoids copying the entire data. Also, pointer receivers are necessary when you want the method to change the struct's fields. Value receivers are simpler and safe when you only need to read data or work with small structs.

⚖️

Code Comparison

go
package main

import "fmt"

type Counter struct {
    Count int
}

// Value receiver method
func (c Counter) Increment() {
    c.Count++
    fmt.Println("Inside Increment (value receiver):", c.Count)
}

func main() {
    c := Counter{Count: 1}
    c.Increment()
    fmt.Println("After Increment call:", c.Count)
}
Output
Inside Increment (value receiver): 2 After Increment call: 1
↔️

Pointer Receiver Equivalent

go
package main

import "fmt"

type Counter struct {
    Count int
}

// Pointer receiver method
func (c *Counter) Increment() {
    c.Count++
    fmt.Println("Inside Increment (pointer receiver):", c.Count)
}

func main() {
    c := Counter{Count: 1}
    c.Increment()
    fmt.Println("After Increment call:", c.Count)
}
Output
Inside Increment (pointer receiver): 2 After Increment call: 2
🎯

When to Use Which

Choose value receivers when your method does not need to modify the struct and the struct is small, like simple data or immutable values. This keeps your code safe from accidental changes.

Choose pointer receivers when your method needs to change the struct's fields or when the struct is large and copying it would be inefficient. Pointer receivers also allow consistency if some methods need to modify the struct.

Key Takeaways

Pointer receivers allow methods to modify the original struct, value receivers do not.
Value receivers work on copies and are best for small, immutable data.
Pointer receivers avoid copying large structs, improving performance.
Use pointer receivers when you want to change struct fields inside methods.
Value receivers can be called on both values and pointers, pointer receivers require pointers.