I have just came across this piece of code on this blog post
type Logger interface {
Debug(msg string, keyvals ...interface{}) error
Info(msg string, keyvals ...interface{}) error
Error(msg string, keyvals ...interface{}) error
}
type tmLogger struct {
srcLogger kitlog.Logger
}
// Interface assertions
var _ Logger = (*tmLogger)(nil) // What is this?
// ... interface definition ...
What is this "interface assertion"?
It assigns a nil pointer to a concrete type to a variable of the interface type. This is a common practice to prove that the concrete type fulfills the interface - if it doesn't, that line won't compile, giving an error that the concrete type can't be assigned to a variable of the interface type and why.
As @JimB noted, "interface assertion" is a term made up by the author. Go has no such term. This is, specifically, a type conversion, converting nil
to a pointer to tmLogger
, then assigning the typed nil pointer to a blank identifier variable of the interface type Logger
. If *tmLogger
does not satisfy Logger
, the assignment won't compile; but, at runtime, this takes no memory because it's using a nil value.
Presumably the author uses this term more in the unit-testing sense of "assertion" than the "type assertion" sense - that line of code asserts that the type implements the interface, and if it doesn't, the line will fail.
Given that this is purely a testing practice, personally I put these checks in _test.go files so that they're included in unit test executions, excluded from the final binary, and clearly part of the test suite and not the application logic.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With