问题
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"?
回答1:
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.
来源:https://stackoverflow.com/questions/44976862/what-is-an-interface-assertion