← Back to Go Course | Chapter 6: Structs & Methods | Lesson 4 of 6

Value vs Pointer Receivers

A value receiver works on a photocopy of your struct, but a pointer receiver reaches back and edits the real original.

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

markup
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)
}

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

markup
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)
}

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

markup
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)
}
Common Mistakes
  1. 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.
  2. Mixing value and pointer receivers inconsistently across a type's methods, which can make an interface implementation harder to reason about.
  3. Using a pointer receiver purely out of habit on tiny structs where a value receiver would be simpler and just as efficient.
Chapter Summary
  • 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:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.