Monday, February 9, 2026
Interfaces
Akash AmanUpdated: February 2026
Interfaces
The Interface Definition
Concept: A type that specifies a set of method signatures. It defines what an object can do, rather than what it is.
- Behavior: Unlike structs (which hold state/data), interfaces hold contracts. Any type that implements all methods in an interface is said to satisfy that interface.
- Why: This allows for Polymorphism. You can write a single function that works with any type, as long as that type has the required methods.
Implicit Implementation (The "Duck Typing" of Go)
Concept: In Go, you do not use an implements keyword. A type satisfies an interface automatically by having the required methods.
- Behavior: This is "decoupled" design. A developer can create a struct in one package, and a user can create an interface in another package to "wrap" that struct without the original developer ever knowing about it.
- Why: It reduces boilerplate and makes code incredibly flexible. If it walks like a duck and quacks like a duck, Go treats it as a duck.
The Empty Interface (interface{} or any)
Concept: An interface that has zero methods.
- Behavior: Since every type has at least zero methods, every type satisfies the empty interface. In Go 1.18+, the keyword
anywas introduced as an alias forinterface{}. - Why: Used when you don't know the type of data beforehand (like
fmt.Printlnwhich accepts anything). However, it should be used sparingly as it bypasses Go's type safety.
Interface Values & Dynamic Dispatch
Concept: Under the hood, an interface value is a small tuple of two pointers: one to the concrete type information and one to the actual data.
- Behavior: When you call a method on an interface, Go uses these pointers to find the right method to run at runtime.
- Why: This is how Go remains a statically typed language while behaving dynamically. It knows exactly what the underlying "thing" is, even if it's hiding behind an interface.
Composition & Advanced Patterns
Interface Embedding (Composition)
Concept: Combining multiple interfaces into a larger one.
Setup:
- Interface Structure
- Why: It promotes the Interface Segregation Principle. You can define small, focused interfaces and compose them into bigger ones only when needed. It keeps your code clean and reusable.
Type Assertions & Switches
Concept: A way to "extract" the underlying concrete type from an interface.
- Behavior: You can ask the interface: "Are you actually a Circle?"
- Why: This allows you to regain access to specific fields of a struct (like
Radius) that are hidden when the struct is being treated as a general interface.
Reference Guides
Implementation Rules
| Rule | Explanation | Result |
|---|---|---|
| Value vs Pointer | Methods can be defined on T or *T. | Affects which types satisfy the interface. |
| Nil Interfaces | An interface with no type and no value is nil. | Calling a method on a nil interface causes a panic. |
| Small is Better | Go convention favors 1-2 method interfaces (e.g., io.Reader). | Makes the interface easier to implement and reuse. |
Summary Table
| Concept | Purpose | Developer Impact |
|---|---|---|
| Implicit | Decoupling | You don't need to declare dependencies upfront. |
any | Flexibility | Allows functions to handle unknown types. |
| Embedding | Composition | Build complex behaviors from simple parts. |
| Assertions | Recovery | Safe way to convert interfaces back to concrete types. |