JSTAcademy
0 XP
Dashboard
Crash Courses
Structs, Methods & Interfaces
35 min
Masters+175 XP
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().

0%