Introduction
Go does not have classes, but it lets you attach methods to any named type using a special receiver argument. A method is simply a function with an extra parameter, called the receiver, placed between the func keyword and the method name. This lets types defined in your package expose behavior directly, similar in spirit to methods in object-oriented languages.
Cricket analogy: Like attaching a strike-rate calculation directly to a Batsman type via a receiver, so calling batsman.StrikeRate() reads naturally, similar to how OOP languages bundle behavior with the batting stats object.
Syntax
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}Explanation
The receiver (r Rectangle) in Area is a value receiver: it receives a copy of the Rectangle, so calling Area cannot modify the original struct. The receiver (r *Rectangle) in Scale is a pointer receiver: it receives a pointer to the original struct, so mutations inside Scale affect the caller's value directly and avoid copying the whole struct. Value receivers are appropriate for read-only methods or small types, while pointer receivers are preferred when the method needs to mutate the receiver or when the type is large and copying would be wasteful. Go automatically takes the address of an addressable value when calling a pointer-receiver method, so r.Scale(2) works even if r is not a pointer variable.
Cricket analogy: Like handing a scorekeeper a photocopy of the scoreboard to calculate the average with a value receiver versus handing them the actual scoreboard to update after a six with a pointer receiver, Go auto-lets r.Scale(2) work on the original board.
Example
package main
import "fmt"
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
func (r *Rectangle) Scale(factor float64) {
r.Width *= factor
r.Height *= factor
}
func main() {
rect := Rectangle{Width: 3, Height: 4}
fmt.Println("Area:", rect.Area())
rect.Scale(2)
fmt.Println("After scale:", rect.Width, rect.Height)
fmt.Println("New area:", rect.Area())
}
// Output:
// Area: 12
// After scale: 6 8
// New area: 48Key Takeaways
- A method is a function with a receiver argument written between func and the method name.
- Methods can be attached to any named type defined in the same package, not just structs.
- Value receivers operate on a copy and cannot modify the original data.
- Pointer receivers operate on the original data and can mutate it, avoiding unnecessary copying.
- Go has no classes; methods on named types provide similar organization of behavior and data.
Practice what you learned
1. Where is a method's receiver written in Go?
2. What is the key difference between a value receiver and a pointer receiver?
3. Why would you choose a pointer receiver for a method?
4. Does Go have traditional classes for defining methods?
Was this page helpful?
You May Also Like
Functions in Go
Learn how to declare, call, and use functions as first-class values in Go.
Structs in Go
A composite type that groups related fields together, forming the basis for custom data modeling in Go.
Pointers in Go
A variable that holds the memory address of another value, enabling shared access and mutation without copying.
Interfaces in Go
Learn how Go interfaces define behavior through implicit, structural typing without classes or inheritance.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics