Methods on Structs
Value receivers vs pointer receivers
Methods on Structs is a free Go Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is a Method?
A method is a function with a receiver argument. The receiver appears between the func keyword and the method name, binding the function to a type.
Value Receiver
A value receiver receives a copy of the struct. Use when the method doesn't need to mutate state:
package main
import "fmt"
type Circle struct{ Radius float64 }
func (c Circle) Area() float64 {
return 3.14159 * c.Radius * c.Radius
}
func main() {
c := Circle{Radius: 5}
fmt.Printf("%.2f\n", c.Area()) // 78.54
}Pointer Receiver
A pointer receiver allows the method to mutate the struct. More efficient for large structs:
package main
import "fmt"
type Counter struct{ N int }
func (c *Counter) Increment() { c.N++ }
func (c *Counter) Reset() { c.N = 0 }
func main() {
c := Counter{}
c.Increment(); c.Increment()
fmt.Println(c.N) // 2
c.Reset()
fmt.Println(c.N) // 0
}When to Use Pointer Receivers
Use pointer receivers when:
- The method needs to modify the receiver
- The struct is large (avoids copying)
- Consistency: if any method has a pointer receiver, all should
Use value receivers when the struct is small and the method only reads data.
Method Expressions and Values
Methods can be used as first-class values:
package main
import "fmt"
type Adder struct{ Base int }
func (a Adder) Add(n int) int { return a.Base + n }
func main() {
a := Adder{Base: 10}
fn := a.Add // method value — bound to a
fmt.Println(fn(5)) // 15
}Methods on Non-Struct Types
You can define methods on any named type in the same package, not just structs:
package main
import "fmt"
type Celsius float64
func (c Celsius) ToFahrenheit() float64 {
return float64(c)*9/5 + 32
}
func main() {
t := Celsius(100)
fmt.Println(t.ToFahrenheit()) // 212
}Automatic Pointer Dereferencing
Go automatically takes the address or dereferences when calling methods. You don't need to write (&c).Method() manually:
package main
import "fmt"
type Box struct{ Val int }
func (b *Box) Double() { b.Val *= 2 }
func main() {
b := Box{Val: 5}
b.Double() // Go auto-takes address
fmt.Println(b.Val) // 10
}Chaining Methods
Return the receiver pointer to enable method chaining (builder pattern):
package main
import "fmt"
type Builder struct{ result string }
func (b *Builder) Add(s string) *Builder {
b.result += s
return b
}
func (b *Builder) Build() string { return b.result }
func main() {
s := (&Builder{}).Add("Hello").Add(", ").Add("World").Build()
fmt.Println(s)
}String Method (fmt.Stringer)
Implement the String() string method to control how a type is printed:
package main
import "fmt"
type Point struct{ X, Y int }
func (p Point) String() string {
return fmt.Sprintf("(%d, %d)", p.X, p.Y)
}
func main() {
p := Point{3, 4}
fmt.Println(p) // (3, 4)
}Nil Pointer Receivers
A method with a pointer receiver can be called on a nil pointer — useful for default behaviors:
package main
import "fmt"
type Node struct{ Val int }
func (n *Node) Value() int {
if n == nil { return 0 }
return n.Val
}
func main() {
var n *Node
fmt.Println(n.Value()) // 0
}Consistency Principle
In Go's standard library and idiomatic Go, all methods on a type use the same receiver kind — all pointer or all value. Mixing causes subtle bugs with interfaces.
Quick Check
Which receiver type allows a method to modify the struct's fields?
Recap: Methods
Key takeaways:
- Methods have a receiver between
funcand the name - Value receivers: read-only, small structs
- Pointer receivers: mutation, large structs, consistency
- Go auto-dereferences — no need to write
(&v).Method() - Implement
String() stringfor custom printing
Practice Prompt
Define a BankAccount struct with a Balance float64 field. Add Deposit and Withdraw pointer-receiver methods and a String() value-receiver method.
Frequently asked questions
Is the “Methods on Structs” lesson free?
Yes — the full text of “Methods on Structs” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Methods on Structs”?
Value receivers vs pointer receivers You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Methods on Structs” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.