Interface Guards In Go
Here’s a cool trick to force a compile-time check that a struct satisfies an interface. We call it an interface guard.
Add code like the following to the top of your code to force a compile-time check that a struct satisfies an interface:
var _ SomeInterface = (*SomeType)(nil)
If it doesn’t, you’ll see an error such as:
cannot use (*SomeType)(nil) (value of type *SomeType) as SomeInterface value in variable declaration: *SomeType does not implement SomeInterface (missing SomeMethod method)
You shouldn’t need to do this all the time, but let me tell you why it can be useful.
In Go, interfaces are implicit. This means you do not have to declare that a type implements an
interface. By adding the above, you are making it 100% clear that it is your intention that SomeType
implements
SomeInterface
. It also helps with auto-complete in IDEs and guards against breaking changes.
Here is another, more concrete example from Uber’s style guide:
Bad
type A struct{}
func New() A {
return A{}
}
func (a A) Read(p []byte) (n int, err error) {
panic("implement me")
}
func (a A) Close() error {
panic("implement me")
}
Good
type A struct{}
var _ io.ReadCloser = (*A)(nil)
func New() A {
return A{}
}
func (a A) Read(p []byte) (n int, err error) {
panic("implement me")
}
func (a A) Close() error {
panic("implement me")
}