Introduction
Go's simplicity and power shine in its interface system, offering a clean way to define contracts between types. However, when it comes to checking whether a struct satisfies an interface, Go's static typing philosophy means there isn't a direct runtime check. In this concise guide, we'll explore practical methods, including some lesser-known tricks, to verify whether a struct implements an interface.
Method 1: Type Assertion and a Dummy Method
package main
import "fmt"
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (ms MyStruct) MyMethod() {
fmt.Println("MyMethod implementation")
}
func main() {
var myVar interface{} = MyStruct{}
_, ok := myVar.(MyInterface)
fmt.Println("Implements MyInterface:", ok)
}
This method employs type assertion to attempt a cast and check the success with a boolean variable.
Method 2: Reflection
package main
import (
"fmt"
"reflect"
)
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (ms MyStruct) MyMethod() {
fmt.Println("MyMethod implementation")
}
func implementsInterface(i interface{}, ifacePtr interface{}) bool {
return reflect.TypeOf(i).Implements(reflect.TypeOf(ifacePtr).Elem())
}
func main() {
var myVar MyStruct
fmt.Println("Implements MyInterface:", implementsInterface(myVar, (*MyInterface)(nil)))
}
Reflection allows checking if a type implements an interface by comparing type information.
Method 3: Embedding Interfaces
package main
import (
"fmt"
"reflect"
)
type MyInterface interface {
MyMethod()
}
type MyStruct struct{}
func (ms MyStruct) MyMethod() {
fmt.Println("MyMethod implementation")
}
func implementsInterface(i interface{}, ifacePtr interface{}) bool {
return reflect.TypeOf(i).Implements(reflect.TypeOf(ifacePtr).Elem())
}
func main() {
var myVar MyStruct
fmt.Println("Implements MyInterface:", implementsInterface(myVar, (*MyInterface)(nil)))
}
By embedding the interface, we can use a type assertion to check for direct or embedded implementation.
Compile-time Check with guru
For a robust compile-time check, leverage the golang.org/x/tools/cmd/guru
tool:
go get golang.org/x/tools/cmd/guru
guru implements MyInterface ./...
This tool performs a static analysis to check if a type implements an interface across the entire codebase.
Conclusion
While Go's design philosophy favors compile-time checks, these runtime and tooling techniques provide practical solutions to check interface implementations. Choose the method that aligns with your project's needs and coding style.