>_
GolangStepByStep
Intern

Interfaces

Define behaviour with interfaces — Go's key abstraction mechanism

# Why Interfaces Matter

Interfaces are Go's decoupling tool. They let callers depend on behavior, not concrete implementations, which improves testability and maintainability.

Go interfaces are implicit and usually small. This makes them easy to satisfy and ideal for boundary design in services.

# Implicit Satisfaction

A type implements an interface by having required methods—no declaration keyword needed.

type Animal interface {
    Sound() string
    Name() string
}

type Dog struct{ name string }
func (d Dog) Sound() string { return "Woof" }
func (d Dog) Name() string  { return d.name }

# Core Interfaces: error and io.Reader

The `error` and `io.Reader` patterns show how one-method interfaces unlock broad reuse.

type ValidationError struct {
    Field string
    Message string
}

func (e *ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

# Nil Interface Gotcha

A nil interface differs from an interface holding a typed nil pointer. This is a frequent interview and production bug.

# Practice Challenge

Define Shape with area/perimeter and buildTotalArea over []Shape.

package main

import (
    "fmt"
    "math"
)

type Shape interface {
    Area() float64
    Perimeter() float64
}

type Circle struct{ Radius float64 }
type Rectangle struct{ W, H float64 }

func TotalArea(shapes []Shape) float64 {
    // TODO
}

⚡ Key Takeaways

  • Interfaces are satisfied implicitly by method sets
  • Small interfaces lead to better reuse and testability
  • Use interface boundaries to decouple caller from implementation
  • Watch for nil interface vs typed nil pointer differences
practice & review