Interfaces
Implicit satisfaction
Section titled “Implicit satisfaction”Go interfaces are satisfied implicitly — there’s no implements keyword. If a type has the right methods, it satisfies the interface, full stop.
type Stringer interface { String() string}
type Point struct{ X, Y int }
func (p Point) String() string { return fmt.Sprintf("(%d, %d)", p.X, p.Y)}Point now satisfies Stringer without ever mentioning it. This decouples the interface’s definition from its implementations — you can define an interface for types you don’t own.
Small interfaces are idiomatic
Section titled “Small interfaces are idiomatic”The standard library’s most-used interfaces are tiny:
type Reader interface { Read(p []byte) (n int, err error)}
type Writer interface { Write(p []byte) (n int, err error)}io.Reader and io.Writer are one method each, yet files, network connections, byte buffers, and compressors all implement them — letting you write code like io.Copy(dst, src) that works with any combination.
The empty interface and type assertions
Section titled “The empty interface and type assertions”interface{} (or any, its alias since Go 1.18) is satisfied by every type — useful for genuinely dynamic data, though generics (covered later) now handle most cases that used to need it.
var v any = "hello"
s, ok := v.(string) // type assertionif ok { fmt.Println(s)}
switch x := v.(type) {case string: fmt.Println("string:", x)case int: fmt.Println("int:", x)default: fmt.Println("unknown type")}