英文:
What is an interface assertion?
问题
我刚在这篇博客文章上看到了这段代码:
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) // 这是什么?
// ... 接口定义 ...
这个"interface assertion"是什么意思?
英文:
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
得分: 14
它将一个nil指针分配给一个接口类型的变量,这是一种常见的做法,用来证明具体类型满足接口——如果不满足,那行代码就无法编译,会报错说具体类型无法赋值给接口类型的变量,以及原因。
正如@JimB所指出的,“接口断言”是作者杜撰的术语,Go语言中没有这样的术语。具体来说,这是一种类型转换,将nil
转换为指向tmLogger
的指针,然后将类型化的nil指针赋给接口类型Logger
的空标识符变量。如果*tmLogger
不满足Logger
,赋值将无法编译;但在运行时,这不会占用内存,因为它使用的是一个nil值。
假设作者更多地在单元测试的意义上使用这个术语,而不是“类型断言”的意义——这行代码断言该类型实现了该接口,如果不满足,该行代码将失败。
鉴于这纯粹是一种测试实践,个人会将这些检查放在_test.go文件中,这样它们就会包含在单元测试执行中,从最终的二进制文件中排除,并清楚地成为测试套件的一部分,而不是应用程序逻辑的一部分。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论