Crash Courses · Masters
Structs, Methods & Interfaces
Compose data, attach behaviour, and write polymorphic code
35 min read+175 XP on completionCert: Go Crash Course
Tap any word in the text below to start reading from there.
Structs, Methods & Interfaces
Structs
type User struct {
ID int
Name string
Email string
Admin bool
}
// Struct literal
u := User{ID: 1, Name: "Jordan", Email: "j@example.com"}
fmt.Println(u.Name) // Jordan
// Anonymous struct (useful for quick groupings)
point := struct{ X, Y int }{X: 3, Y: 4}Methods
// Value receiver — operates on a copy
func (u User) String() string {
return fmt.Sprintf("User(%d, %s)", u.ID, u.Name)
}
// Pointer receiver — can mutate the struct
func (u *User) Promote() {
u.Admin = true
}
func main() {
u := User{ID: 1, Name: "Jordan"}
fmt.Println(u.String()) // User(1, Jordan)
u.Promote()
fmt.Println(u.Admin) // true
}Use pointer receivers for methods that mutate state or for large structs (avoids copying).
Interfaces
An interface is a contract. Any type that has all the required methods satisfies it automatically:
type Shape interface {
Area() float64
Perimeter() float64
}
type Rectangle struct {
Width, Height float64
}
func (r Rectangle) Area() float64 { return r.Width * r.Height }
func (r Rectangle) Perimeter() float64 { return 2 * (r.Width + r.Height) }
type Circle struct {
Radius float64
}
func (c Circle) Area() float64 { return math.Pi * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * math.Pi * c.Radius }
// Polymorphic function — works with any Shape
func printShape(s Shape) {
fmt.Printf("Area: %.2f Perimeter: %.2f\n", s.Area(), s.Perimeter())
}
func main() {
printShape(Rectangle{3, 4})
printShape(Circle{5})
}The Empty Interface
interface{} (or any in Go 1.18+) is satisfied by every type — use it only when you genuinely need a container of mixed types.
Embedding
type Animal struct {
Name string
}
func (a Animal) Speak() string { return "..." }
type Dog struct {
Animal // embedded — Dog gets Speak() for free
Breed string
}
d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Lab"}
fmt.Println(d.Speak()) // ... (promoted method)
fmt.Println(d.Name) // Rex (promoted field)Stringer Interface
If your type implements String() string it satisfies fmt.Stringer and fmt.Println will call it automatically — exactly like Java's toString().
Reading progress
0% read
In this module
struct
method
value receiver
pointer receiver
0%