Interfaces in Go
What is an Interface?
An interface in Go defines a set of method signatures. Any type that implements all those methods automatically satisfies the interface — no explicit declaration needed.
Defining an Interface
You define an interface with the type keyword and list the method signatures inside:
Implicit Implementation
Unlike Java or C#, Go has no implements keyword. A type satisfies an interface simply by having the right methods. This is called structural typing or duck typing.
Implementing an Interface
Any struct (or other type) with the required methods automatically satisfies the interface.
Defining Concrete Types
Here both Dog and Cat satisfy the Animal interface without ever mentioning it:
The Empty Interface
The empty interface interface{} (or any in modern Go) has no methods, so every type satisfies it automatically. It is Go’s way of expressing “any value”.
When to Use any
Use any when you genuinely need to store values of unknown type — for example in generic containers or when decoding JSON.
Type Assertions
To get the underlying concrete value back out, use a type assertion:
Type Switches
A type switch lets you branch on the dynamic type of an interface value:
Common Standard-Library Interfaces
Go’s standard library is built around small, composable interfaces.
The Stringer Interface
fmt.Stringer is satisfied by any type with a String() string method. The fmt package calls it automatically when printing:
The error Interface
error is just a built-in interface with one method:
Any type with an Error() string method can be returned as an error.
io.Reader and io.Writer
These two interfaces underpin almost all I/O in Go:
Files, network connections, buffers, and HTTP bodies all implement one or both.
Interface Composition
Interfaces can embed other interfaces to build larger contracts from smaller ones.
Embedding Interfaces
io.ReadWriter is simply the union of Reader and Writer:
A type must implement all methods of all embedded interfaces to satisfy the composed interface.
Keeping Interfaces Small
The Go community prefers small, focused interfaces over large ones. The standard library’s most-used interfaces have just one or two methods. This makes them easy to satisfy and easy to mock in tests.
Nil Interfaces and Pitfalls
A Nil Interface vs a Nil Pointer
An interface value has two parts: a type and a value. An interface is nil only when both are nil. This leads to a common surprise:
Returning Concrete Types vs Interfaces
Return concrete types from constructors and accept interfaces as parameters. This keeps your API flexible without over-abstracting.