Go Gopher How to Go

An interface in Go is a collection of method signatures. A value implements an interface by implementing its methods. There is no explicit declaration of intent.

💡 Key Points

  • Interfaces specify method signatures
  • Implementation is implicit
  • Empty interface accepts any value
  • Enables polymorphism
  • Small interfaces preferred
  • Use assertions for underlying values

Defining and Implementing Interfaces

Define an interface by listing method signatures:

package main

import (
    "fmt"
    "math"
)

// Define an interface
type Shape interface {
    Area() float64
}

// Rectangle implements Shape
type Rectangle struct {
    Width, Height float64
}

func (r Rectangle) Area() float64 {
    return r.Width * r.Height
}

// Circle implements Shape
type Circle struct {
    Radius float64
}

func (c Circle) Area() float64 {
    return math.Pi * c.Radius * c.Radius
}

func PrintArea(s Shape) {
    fmt.Println("Area:", s.Area())
}

func main() {
    rect := Rectangle{Width: 10, Height: 5}
    circ := Circle{Radius: 7}
    
    PrintArea(rect)
    PrintArea(circ)
}
Output:
Area: 50
Area: 153.93804002589985

The Empty Interface

The empty interface specifies zero methods and can hold values of any kind:

package main

import "fmt"

func describe(i interface{}) {
    fmt.Printf("(%v, %T)\n", i, i)
}

func main() {
    var i interface{}
    describe(i)
    
    i = 42
    describe(i)
    
    i = "hello"
    describe(i)
}
Output:
(<nil>, <nil>)
(42, int)
(hello, string)

Type Assertions

A type assertion provides access to an underlying concrete value:

package main

import "fmt"

func main() {
    var i interface{} = "hello"
    
    s := i.(string)
    fmt.Println(s)
    
    s, ok := i.(string)
    fmt.Println(s, ok)
    
    f, ok := i.(float64)
    fmt.Println(f, ok)
}
Output:
hello
hello true
0 false

Common Standard Interfaces

InterfaceMethodsPurpose
fmt.StringerString() stringCustom string representation
errorError() stringError handling
io.ReaderRead([]byte) (int, error)Read data from source
io.WriterWrite([]byte) (int, error)Write data to destination
io.CloserClose() errorRelease resources

Best Practices

PracticeGuidelineReason
Small contractsPrefer 1-3 methodsEasier to implement
Accept contractsParameters should be contractsMore flexible
Output structsOutput concrete valuesClearer API
Define at use siteConsumer defines contractsMinimal dependencies