Interface compliance at compile-time in Go
How to be sure that your struct implements the interface

Software Engineer x Data Engineer - I make the world a better place to live with software that enables data-driven decision-making
Interfaces
Imagine having an interface called Runner that looks like this:
type Runner interface {
Run() error
}
And a struct called Worker that you want to implement the mentioned interface. What you need to do? Ofc the only thing required is to add a Run function according to the interface:
type Worker struct {
}
func (w Worker) Run() error {
return nil
}
Voilà! Now your Worker struct implements the Runner interface.
The whole program now looks like this:
package main
import "fmt"
type Runner interface {
Run() error
}
type Worker struct {
}
func (w Worker) Run() error {
return nil
}
func main() {
w := Worker{}
fmt.Println("worker", w)
}
You can run your program and everything is fine:
➜ interfaces git:(main) ✗ go run main.go
worker {}
Interface Mutation → Problem
Okay, but what will happen if you change the Runner interface?
type Runner interface {
Run() error
Stop() error
}
Well, you run the program and… nothing happens. Program runs successfully, but Worker is no longer compliant with the Runner interface, bc it’s missing the Stop function:
➜ interfaces git:(main) ✗ go run main.go
worker {}
Compile-time Compliance
How to be sure that your struct implements the interface at a complie-time? That’s easy! You just need to add this line:
var _ Runner = (*Worker)(nil)
What it does, you ask?
The underscore
_is used only as a blank identifier, means to ignore the value.The
Runneris theinterfacethat we want to check.And the right side of the assignement is a type conversion of
nilto apointerof theWorkerstruct.
Thanks to this we enforce at the compile-time that the given type (Worker) implements the interface (Runner).
Having the main packages like this (with the missing Stop function in the Worker):
package main
import "fmt"
type Runner interface {
Run() error
Stop() error
}
var _ Runner = (*Worker)(nil)
type Worker struct {
}
func (w Worker) Run() error {
return nil
}
func main() {
w := Worker{}
fmt.Println("worker", w)
}
When we try to run this program:
➜ interfaces git:(main) ✗ go run main.go
# command-line-arguments
./main.go:10:16: cannot use (*Worker)(nil) (value of type *Worker) as Runner value in variable declaration: *Worker does not implement Runner (missing method Stop)
We got a compile-time error.
Let’s fix this quickly by adding a missing Stop function:
func (w Worker) Stop() error {
return nil
}
And we’re good:
➜ kiss-samples git:(main) ✗ go run main.go
worker {}
That’s it! Hope you like it and use it in your own projects!




