Value vs Pointer Receivers
In this page:
Value Receivers Copy
A method with a value receiver gets its own independent copy of the struct -- any changes it makes inside the method are invisible once the method returns, because they happened to the copy, not the original.
Example: Value Receivers Copy
package main
import "fmt"
type Counter struct {
Value int
}
func (c Counter) IncrementValue() {
c.Value++ // modifies the copy only
}
func main() {
c := Counter{Value: 0}
c.IncrementValue()
fmt.Println("still:", c.Value)
}
Login to try C/C++/Java/PHP code in the editor
Pointer Receivers Mutate
A method with a pointer receiver operates directly on the original struct through its address, so changes made inside the method are visible to the caller after it returns.
Example: Pointer Receivers Mutate
package main
import "fmt"
type Counter struct {
Value int
}
func (c *Counter) IncrementValue() {
c.Value++ // modifies the original
}
func main() {
c := Counter{Value: 0}
c.IncrementValue()
fmt.Println("now:", c.Value)
}
Login to try C/C++/Java/PHP code in the editor
Automatic Addressing
Go lets you call a pointer-receiver method directly on a plain (addressable) struct value, like c.IncrementValue(), by automatically taking its address behind the scenes -- you don't have to write (&c).IncrementValue() yourself.
Example: Automatic Addressing
package main
import "fmt"
type Account struct {
Balance float64
}
func (a *Account) Deposit(amount float64) {
a.Balance += amount
}
func main() {
acc := Account{Balance: 100}
acc.Deposit(50) // Go automatically does (&acc).Deposit(50)
fmt.Println(acc.Balance)
}
Login to try C/C++/Java/PHP code in the editor
- Using a value receiver for a method that's supposed to modify the struct, then being confused why the change doesn't persist outside the method.
- Mixing value and pointer receivers inconsistently across a type's methods, which can make an interface implementation harder to reason about.
- Using a pointer receiver purely out of habit on tiny structs where a value receiver would be simpler and just as efficient.
- A value receiver, func (t Type) M(), operates on a copy of the value.
- A pointer receiver, func (t *Type) M(), operates on the original value and can modify it.
- Go automatically takes the address for you when calling a pointer-receiver method on an addressable value.
- Use pointer receivers when the method needs to mutate the receiver or the struct is large.
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: