Go – Interfaces Explained with Syntax, Examples, and Use Cases (2025 Guide)
Introduction – What Are Interfaces in Go?
In Go, an interface is an abstract type that defines a method set. Any type that implements those methods is said to satisfy the interface, without explicitly declaring it. Interfaces provide flexibility, polymorphism, and support dependency injection in Go’s composition-over-inheritance model.
In this section, you’ll learn:
- How to declare and implement interfaces
- How dynamic dispatch works in Go
- How to use interfaces in real-world applications
- Differences between empty and typed interfaces
Define and Implement a Basic Interface
type Speaker interface {
Speak() string
}
type Human struct{}
func (h Human) Speak() string {
return "Hello!"
}
Human implicitly satisfies the Speaker interface by implementing the Speak() method.
Use Interface Values in Functions
func greet(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
var h Human
greet(h)
}
Output:
Hello!
Functions can accept any type that satisfies the interface.
Multiple Types Implementing the Same Interface
type Dog struct{}
func (d Dog) Speak() string { return "Woof!" }
type Robot struct{}
func (r Robot) Speak() string { return "Beep!" }
func main() {
speakers := []Speaker{Dog{}, Robot{}}
for _, s := range speakers {
fmt.Println(s.Speak())
}
}
Output:
Woof!
Beep!
Enables polymorphic behavior without inheritance.
Empty Interface (interface{})
The empty interface can hold any type because every type implements zero methods.
var val interface{}
val = 42
fmt.Println(val) // Output: 42
val = "GoLang"
fmt.Println(val) // Output: GoLang
Used for generic containers, JSON unmarshaling, and reflection.
Type Assertion and Type Switch
var i interface{} = "Gopher"
str, ok := i.(string)
if ok {
fmt.Println("It's a string:", str)
}
Use type assertion to safely extract values from interface{}.
switch v := i.(type) {
case string:
fmt.Println("String:", v)
case int:
fmt.Println("Integer:", v)
default:
fmt.Println("Unknown type")
}
Type switches help handle multiple dynamic types at runtime.
Interface Composition (Embedding)
type Reader interface {
Read() string
}
type Writer interface {
Write(string)
}
type ReadWriter interface {
Reader
Writer
}
Interfaces can be composed from smaller interfaces to create modular APIs.
Interface vs Struct – Key Differences
| Feature | Struct | Interface |
|---|---|---|
| Contains | Data fields | Method signatures only |
| Implements | Concrete type | Abstract behavior |
| Inheritance | No inheritance | Uses composition |
| Polymorphism | Not inherently polymorphic | Enables polymorphism |
Best Practices
| Practice | Why It Matters |
|---|---|
| Define interfaces by behavior | Improves flexibility and testability |
| Use small, focused interfaces | Promotes separation of concerns |
| Don’t use empty interface often | Avoids runtime errors and complexity |
| Rely on implicit implementation | Reduces boilerplate |
Summary – Recap & Next Steps
Interfaces are Go’s powerful way to support polymorphism, flexibility, and clean architecture. They enable different types to be used interchangeably as long as they satisfy the required behavior.
Key Takeaways:
- Interfaces define method contracts, not data
- Any type satisfying the methods automatically implements the interface
interface{}can hold any type, but use with care- Use interfaces for flexible APIs and testability
Next: Explore Go Interface Embedding, Interface vs Type Comparison, or Mocking with Interfaces.
FAQs – Go Interfaces
Do I need to explicitly declare that a type implements an interface?
No. Go uses implicit implementation—you just need to define the methods.
Can a type implement multiple interfaces?
Yes. A type can implement any number of interfaces.
What is the zero value of an interface?
The zero value is nil.
Is interface{} the same as any in Go 1.18+?
Yes. any is an alias for interface{}.
Can I compare interfaces in Go?
Yes, if the underlying value is comparable.
Share Now :
