Pointer vs Value Receivers
Part of the Object Oriented Programming section of Coddy's GO journey — lesson 8 of 107.
Methods can have either a value receiver or a pointer receiver. A value receiver works on a copy of the struct. A pointer receiver works on the original struct and can modify its fields.
Value receiver — works on a copy
type Counter struct {
Count int
}
func (c Counter) GetCount() int {
return c.Count
}
// This does NOT modify the original
func (c Counter) IncrementWrong() {
c.Count++ // Only changes the copy!
}Pointer receiver — modifies the original
// This DOES modify the original
func (c *Counter) Increment() {
c.Count++
}
func (c *Counter) Reset() {
c.Count = 0
}Using both together
func main() {
counter := Counter{Count: 0}
counter.Increment()
counter.Increment()
fmt.Println(counter.GetCount()) // Output: 2
counter.Reset()
fmt.Println(counter.GetCount()) // Output: 0
}Use a value receiver when the method only reads data. Use a pointer receiver (*StructName) when the method needs to modify the struct's fields. Go automatically handles the referencing — you call both the same way.
Challenge
MediumAdd methods to the Wallet struct using the correct receiver types:
GetBalance— value receiver, returns the current balanceDeposit— pointer receiver, adds amount to balanceWithdraw— pointer receiver, subtracts amount only if sufficient funds
Cheat sheet
Methods can have either a value receiver or a pointer receiver. A value receiver works on a copy of the struct. A pointer receiver works on the original struct and can modify its fields.
Value receiver — works on a copy:
type Counter struct {
Count int
}
func (c Counter) GetCount() int {
return c.Count
}Pointer receiver — modifies the original:
func (c *Counter) Increment() {
c.Count++
}Use a value receiver when the method only reads data. Use a pointer receiver (*StructName) when the method needs to modify the struct's fields.
Try it yourself
package main
import "fmt"
func main() {
var balance, deposit, withdraw float64
fmt.Scan(&balance, &deposit, &withdraw)
w := Wallet{Balance: balance}
fmt.Printf("Balance: %.2f\n", w.GetBalance())
w.Deposit(deposit)
fmt.Printf("After deposit: %.2f\n", w.GetBalance())
w.Withdraw(withdraw)
fmt.Printf("After withdrawal: %.2f\n", w.GetBalance())
fmt.Printf("Final balance: %.2f\n", w.GetBalance())
}This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Fundamentals of Go OOP
External FilesGo Workspace & ModulesPackages & ImportsExported vs Unexported NamesIntroduction to OOP in GoStructs as ClassesDefining Methods on StructsPointer vs Value ReceiversStruct InitializationConstructor FunctionsRecap - Simple Calculator4Interfaces
Introduction to InterfacesImplicit ImplementationInterface as ContractEmpty Interface (any)Type AssertionType SwitchInterface CompositionStringer & Error InterfacesRecap - Shape Calculator7Encapsulation
Exported vs Unexported FieldsPackage-Level EncapsulationGetter & Setter MethodsInformation Hiding in GoRecap - Student Records10Generics (Go 1.18+)
Introduction to GenericsType ParametersType ConstraintsGeneric StructsGeneric Methods WorkaroundRecap - Generic Collection2Types & Structs Deep Dive
Basic & Composite TypesCustom Type DefinitionsStruct TagsAnonymous StructsNested StructsZero Values & DefaultsRecap - Contact Book5Composition Over Inheritance
Why Go Has No InheritanceStruct Embedding BasicsMethod PromotionEmbedding Multiple StructsEmbedding vs AggregationShadowing Embedded MethodsRecap - Employee Hierarchy8Error Handling & OOP
The error InterfaceCustom Error TypesError Wrapping (fmt.Errorf)Sentinel Errorserrors.Is() and errors.As()Panic, Defer, and RecoverRecap - File Parser3Pointers & Memory
Pointer Basics in GoPointers to StructsPass by Value vs ReferenceThe new() FunctionGarbage Collection in GoRecap - Linked List Builder6Polymorphism in Go
Polymorphism via InterfacesDuck Typing in GoInterface Satisfaction RulesPolymorphic CollectionsDependency InjectionRecap - Payment Processor9Concurrency & OOP
Goroutines BasicsChannels & CommunicationBuffered vs Unbuffered ChanSelect Statementsync.Mutex & sync.RWMutexsync.WaitGroupThread-Safe Struct DesignRecap - Worker Pool