What is an interface assertion?

huangapple go评论160阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2017年7月8日 01:48:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/44976862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定