#Go Interfaces Tutorial
Source Code: The full source code for this tutorial is on GitHub: TutorialEdge/Go-Interfaces-Tutorial
By the end of this tutorial, you’ll understand:
- What interfaces are and why Go uses them
- How to define your own interfaces
- How Go satisfies interfaces implicitly — no
implementskeyword needed
Basic Example
If you’re new to Go, you’ll see interface{} (or its modern alias any) frequently in code. A function that accepts interface{} will accept a value of any type.
package main
import (
"fmt"
)
func myFunc(a any) {
fmt.Println(a)
}
func main() {
var my_age int
my_age = 25
myFunc(my_age)
}
Note:
anywas introduced in Go 1.18 as an alias forinterface{}. They are identical — preferanyin modern Go code.
$ go run main.go
25
Why is this Useful?
By accepting any, a function can work with integers, strings, structs, or anything else without knowing the type upfront. It’s Go’s way of saying: “I don’t care what this is, just give me something.”
This flexibility comes with a trade-off — you lose type safety and must use a type assertion to get the concrete value back. Use any sparingly; prefer typed interfaces when you know what behaviour you need.
Defining Interfaces
An interface in Go defines a set of method signatures — a contract. Any type that implements all those methods automatically satisfies the interface. There is no implements keyword.
Say we want a Guitarist interface with a PlayGuitar() method:
type Guitarist interface {
PlayGuitar()
}
Any type with a PlayGuitar() method satisfies Guitarist — even if it was written without knowing this interface exists. This implicit satisfaction is one of Go’s most powerful features.
package main
import "fmt"
type Guitarist interface {
PlayGuitar()
}
type BaseGuitarist struct {
Name string
}
type AcousticGuitarist struct {
Name string
}
func (b BaseGuitarist) PlayGuitar() {
fmt.Printf("%s plays the Bass Guitar\n", b.Name)
}
func (b AcousticGuitarist) PlayGuitar() {
fmt.Printf("%s plays the Acoustic Guitar\n", b.Name)
}
func main() {
var player BaseGuitarist
player.Name = "Paul"
player.PlayGuitar()
var player2 AcousticGuitarist
player2.Name = "Ringo"
player2.PlayGuitar()
}
Because both types implement PlayGuitar(), we can store them together in a []Guitarist slice:
var guitarists []Guitarist
guitarists = append(guitarists, player)
guitarists = append(guitarists, player2)
This lets you write functions that operate on any Guitarist without knowing the concrete type.
Return Values
Real-world interfaces typically include methods with return values. Go supports multiple return values, including error returns, in interface definitions:
type Employee interface {
Name() string
Language() string
Age() int
Random() (string, error)
}
Any type that implements all four methods satisfies Employee. If it implements only some of them, the compiler will reject it.
Satisfying Interfaces
The Go compiler enforces interface satisfaction at compile time. If a type is missing any method, the program won’t compile.
package main
type Employee interface {
Language() string
Age() int
Random() (string, error)
}
type Engineer struct {
Name string
}
func (e Engineer) Language() string {
return e.Name + " programs in Go"
}
func main() {
// This will throw a compile error
var programmers []Employee
elliot := Engineer{Name: "Elliot"}
// Engineer does not implement Employee:
// missing Age() and Random()
programmers = append(programmers, elliot)
}
The compiler error tells you exactly which methods are missing — making interfaces a reliable way to enforce contracts across a codebase.
Frequently Asked Questions
What is an interface in Go?
An interface is a named set of method signatures. Any type that implements all the methods in an interface automatically satisfies it — there is no implements keyword. This implicit satisfaction makes Go interfaces extremely flexible and composable.
What is the difference between interface{} and any in Go?
They are identical. any was introduced in Go 1.18 as a more readable alias for interface{}. Both represent the empty interface — a type with no method requirements that accepts any value. Prefer any in modern Go code.
How does Go know if a type satisfies an interface?
The compiler checks at compile time whether the type has all the methods the interface requires — with matching names, parameter types, and return types. If any method is missing, the build fails with a clear error message.
Can a Go type satisfy multiple interfaces?
Yes. A type can satisfy any number of interfaces simultaneously, as long as it implements all the required methods for each. This is how Go achieves polymorphism without inheritance.
When should I use interfaces in Go?
Use interfaces when you want to write code that works with multiple types, when you want to make code testable by swapping implementations, or when you want to define a contract between packages. Avoid defining interfaces prematurely — define them where they are consumed, not where types are defined.
What is an empty interface in Go?
An empty interface (any or interface{}) has no method requirements, so every type satisfies it. It is useful for generic containers or functions that must accept any value, but it sacrifices type safety. Use typed interfaces whenever possible.
Conclusion
Interfaces are one of Go’s most important features. They let you write flexible, testable code by defining contracts rather than concrete types — and Go’s implicit satisfaction means any type automatically qualifies if it has the right methods.
Key takeaways:
- Interfaces define method sets — not implementations
- Satisfaction is implicit — no
implementskeyword - Use
anyinstead ofinterface{}in Go 1.18+ - The compiler enforces interface satisfaction at build time
For more on Go’s type system, check out the Go Structs Tutorial and Go Methods Tutorial.
Continue Learning
Go JSON Tutorial
In this tutorial, we are going to cover everything you need when it comes to working with JSON in Go.
Build a Go Serverless App in 5 Minutes With Sst
In this video, we are going to look at what it takes to build a serverless application in Go in 5 minutes using SST.
Go Tickers Tutorial
In this tutorial, we are going to look at how you can effectively use tickers in go to periodically execute tasks in your Go applications
Go Modules Tutorial
In this tutorial, we are going to be looking at how you can successfully work with modules in Go!