Methods and interfaces
Attach behaviour with methods and let types satisfy small interfaces implicitly.
- Attach methods to a type with a receiver before the name.
- Use a pointer receiver when the method must change the value.
- Let types satisfy interfaces implicitly by implementing their methods.
- Keep interfaces small, with one or two methods.
In plain English
A method is a function attached to a type through a receiver, which appears before the method name. A value receiver works on a copy of the value, while a pointer receiver works on the value itself, so it can change the original. An interface is a contract that lists methods, and any type that has those methods satisfies the interface automatically, with no explicit declaration. Small interfaces with one or two methods keep that contract easy to satisfy and easy to replace.
Step by step
- 1Write a method by placing a receiver before the function name.
- 2Choose a pointer receiver when the method mutates the value.
- 3Define a small interface listing the methods you need.
- 4Pass a concrete value anywhere the interface is expected.
package main
import "fmt"
type Notifier interface {
Notify() string
}
type Lesson struct {
Title string
minutes int
}
func (l Lesson) Notify() string {
return "Lesson: " + l.Title
}
func (l *Lesson) Complete() {
l.minutes = 0
}
func announce(n Notifier) {
fmt.Println(n.Notify())
}
func main() {
lesson := Lesson{Title: "Methods and interfaces", minutes: 14}
announce(lesson)
lesson.Complete()
fmt.Println(lesson.minutes)
}Common mistakes
- Giving a mutating method a value receiver means the original value never changes.
- Assuming a type must declare which interface it implements is wrong, because satisfaction is implicit.
- Writing an interface with too many methods makes it hard to satisfy and hard to replace.
- Calling a pointer-receiver method on a non-addressable value does not compile.
Satisfy a notifier
Define a type Message with a Text field and a method Notify() string that returns the text, so Message satisfies a Notifier interface with that single method.
type Notifier interface {
Notify() string
}
type Message struct {
Text string
}What happens when you call a pointer-receiver method on a value that is not addressable?
Make it yours.
Keep a private note for this lesson, then turn the key ideas into flashcards you can revisit.
Lock in what you just learned.
Mark this lesson complete to save your place and move one step closer to the certificate.