Sikau

Go · Day 6 · about 40 min

Interfaces

Implicit satisfaction, Stringer, type assertions and type switches.

Nobody signs a contract

In Java or C#, a class must declare implements Shape. In Go, nobody declares anything. If a type has the methods an interface asks for, it satisfies the interface — automatically, even if the interface was written years later in someone else's package. Donovan and Kernighan call this Go's most distinctive feature: interfaces describe behaviour, and types fit them by accident or by design.

That's why one function can print a temperature, an error, a file or your own types: fmt.Println only asks, "do you have a String() method?" Today you'll use interfaces, look inside them with type assertions, and meet the strangest bug in Go: a nil that isn't nil.

Satisfied without saying so

An interface type is a set of method signatures. A value of any type that has those methods can be stored in a variable of the interface type — implicit satisfaction. Calling a method on the interface runs the method of whatever concrete type is inside (dynamic dispatch).

package main

import "fmt"

type Speaker interface {
	Speak() string
}

type Dog struct{}
type Robot struct{ Model string }

func (Dog) Speak() string     { return "Bhau bhau!" }
func (r Robot) Speak() string { return r.Model + " says beep" }

func main() {
	for _, s := range []Speaker{Dog{}, Robot{"R2"}} {
		fmt.Println(s.Speak())
	}
}
  • Method sets matter: if Speak has a pointer receiver, only *Dog satisfies Speaker, and var s Speaker = Dog{} fails to compile with "method Speak has pointer receiver".
  • fmt.Stringer is interface { String() string }; error is interface { Error() string }.
  • any (an alias for interface{}) is satisfied by every type — useful, but it says nothing about the value (mistake #8).
  • Keep interfaces small and define them where they're used, not next to the implementation (mistakes #5–#7): "accept interfaces, return structs".

The rest of this lesson

  • Looking inside: assertions and switchesexplain
  • The nil that isn't nilexplain
  • Pointer receivers and interfacespredict
  • Interface vocabularymatch
  • A type switchfill
  • Shapeswrite code
  • Badge quizquiz
  • What you learnedrecap

Continue this lesson free — run real code in your browser

Continue with Google

See all 10 lessons of Go