Go Interfaces: Describe Behavior, Not Data
Go interfaces define behavior, not data. A type satisfies an interface implicitly by implementing its methods, without an implements keyword. This enables writing flexible functions, like io.Writer handling files or HTTP responses.
Why it exists
To allow functions to operate on values of different concrete types without knowing their specific implementation, promoting flexible and decoupled code. Instead of inheriting from a base class, Go types can satisfy multiple independent behavioral contracts, enabling composition over inheritance.
The mental model
Think of an interface as a job description listing required skills (methods). A struct is a candidate for that job. If the candidate has all the required skills, it implicitly gets the job (satisfies the interface). There's no need to formally declare "I am applying for this job." This is called structural typing: if it walks and talks like a duck, Go considers it a duck.
How it works
An interface type specifies a method set. Any type that defines all methods in that set is said to implement the interface. For example, if an IOWriter interface has a Write(p []byte) (n int, err error) method, any type with that exact method signature (like os.File or bytes.Buffer) can be used wherever an IOWriter is expected. The Go compiler checks this satisfaction automatically at compile time.
When to use it
Use interfaces as function parameters to accept multiple types of data sources or sinks (e.g., io.Reader). Use them to define service contracts for dependency injection and to create mocks for testing. A common Go proverb is "accept interfaces, return structs," which encourages functions to depend on abstract behaviors while returning concrete, ready-to-use types.
When not to use it
Avoid creating interfaces prematurely. Start with concrete types and introduce an interface only when a second type needs to be handled polymorphically. The empty interface, interface{} (an alias for any), accepts any value, but it bypasses static type checking and should be used sparingly. Using it requires type assertions or switches to access the underlying value, which can be verbose and error-prone.
One canonical example
The http.Handler interface defines how to serve HTTP requests. It has just one method: ServeHTTP(ResponseWriter, *Request). Any struct that implements this method can be passed to http.Handle, which registers it to handle requests for a given pattern. This decouples the core routing logic from the specific logic of each endpoint.
Interview question
How does a concrete type in Go become an implementer of an interface?
- a.By inheriting the interface's defined fields and methods from a parent type.
- b.By defining all the methods specified in the interface's method set.Correct
- c.By explicitly declaring its intention to implement the interface using a special keyword.
- d.By embedding the interface type directly into the struct definition.
Why? this is the answer
A type satisfies an interface implicitly by implementing its methods, without an 'implements' keyword. Option B accurately describes this structural typing, where a type automatically satisfies an interface if it provides all the required methods. Option C is incorrect because Go does not use an explicit 'implements' keyword.
Just read this? Test yourself on what you have been reading.
Read the original → go.dev
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on go — each one lists the topics its interview covers.
See open roles