Structs and Methods
Defining custom types with struct, and attaching behavior with methods and receivers.
What you'll learn
- Define a custom type with `struct` and create instances of it
- Attach a method to a struct type using a receiver
- Explain when a pointer receiver is needed instead of a value receiver
Explanation
Go doesn't have classes -- instead, you define a custom data shape with struct: type Point struct { X, Y int }, then create instances with Point{X: 3, Y: 4}.
You attach behavior to a struct with a method: a function with a special receiver parameter before its name, e.g. func (p Point) String() string { return fmt.Sprintf("(%d, %d)", p.X, p.Y) }. Here (p Point) is the receiver -- inside the method, p refers to the specific instance the method was called on.
A receiver can be a value receiver ((p Point), gets a copy) or a pointer receiver ((p *Point), gets a reference to the original). Use a pointer receiver whenever the method needs to modify the struct -- a value receiver's changes only affect its local copy and are lost once the method returns.
Go automatically takes the address of a variable when calling a pointer-receiver method on it, so you can usually call myPoint.Scale(2) directly even if Scale has a pointer receiver, without writing (&myPoint).Scale(2) yourself.
Guided lab
Predict: A struct with value vs pointer receivers
Read this program and predict exactly what it prints.
package main
import "fmt"
type Counter struct {
value int
}
func (c Counter) IncrementCopy() {
c.value++
}
func (c *Counter) IncrementReal() {
c.value++
}
func main() {
c := Counter{value: 0}
c.IncrementCopy()
fmt.Println("After IncrementCopy:", c.value)
c.IncrementReal()
fmt.Println("After IncrementReal:", c.value)
}Stuck? Get a hint.
Common mistakes
- Using a value receiver on a method meant to modify the struct, then being confused when the change doesn't persist outside the method.
- Assuming Go structs work exactly like classes with inheritance -- Go has no inheritance; behavior is attached via methods and composition instead.
- Forgetting that a value receiver method gets a full copy of the struct, which can matter for large structs and performance, not just mutability.
Knowledge check
Takeaway
Use a pointer receiver whenever a method needs to modify the struct persistently -- a value receiver only ever changes its own local copy.
Summary
Structs define custom data shapes; methods attach behavior via a receiver, which must be a pointer receiver for changes to persist outside the method.
References
Your notes
Notes save automatically.
Finished this lesson?
Mark it complete to track your progress and schedule a future review.
AI tutor
The optional AI tutor isn't enabled in this deployment. All lessons, exercises, quizzes, and search work fully without it.