Go Tutorial · Functions and Methods · Lesson 20 of 30

Go Interfaces

Implicit interfaces, polymorphism, the empty interface and type switches.

Implicit implementation

An interface lists method signatures. A type satisfies it automatically by having those methods — there's no implements keyword:

Example 1
package main

import (
	"fmt"
	"math"
)

type Shape interface {
	Area() float64
}

type Circle struct{ R float64 }

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

type Square struct{ Side float64 }

func (s Square) Area() float64 { return s.Side * s.Side }

func main() {
	shapes := []Shape{Circle{R: 1}, Square{Side: 2}}
	total := 0.0
	for _, s := range shapes {
		fmt.Printf("%T area %.2f\n", s, s.Area())
		total += s.Area()
	}
	fmt.Printf("total %.2f\n", total)
}

Output

main.Circle area 3.14
main.Square area 4.00
total 7.14

Run this on your computer — see “Get Started” for setup.

Small interfaces are idiomatic: io.Reader and io.Writer have one method each, and fmt.Stringer is just String() string.

any and type switches

any (alias for interface{}) holds a value of any type. A type switch or type assertion gets the concrete type back:

Example 2
package main

import (
	"fmt"
	"strings"
)

func describe(v any) string {
	switch t := v.(type) {
	case int:
		return fmt.Sprintf("int %d (doubled %d)", t, t*2)
	case string:
		return "string " + strings.ToUpper(t)
	case nil:
		return "nil"
	default:
		return fmt.Sprintf("something else: %T", t)
	}
}

func main() {
	for _, v := range []any{42, "hello", 3.5, []int{1, 2}, nil} {
		fmt.Println(describe(v))
	}
	var x any = "text"
	if s, ok := x.(string); ok {
		fmt.Println("it's a string of length", len(s))
	}
}

Output

int 42 (doubled 84)
string HELLO
something else: float64
something else: []int
nil
it's a string of length 4

Run this on your computer — see “Get Started” for setup.

Test yourself

How does a Go type declare that it implements an interface?

  1. With the implements keyword
  2. It doesn't — having the methods is enough
  3. By embedding the interface
  4. With an annotation
Show answer

Answer: It doesn't — having the methods is enough