为什么要连续声明像 “var _ I = T{}” 和 “var _ I = &T{}” 这样的语句?

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

Why declare like "var _ I = T{}" and "var _ I = &T{}" continuously?

问题

当我阅读docker/distribution源代码的副本时,我发现有一些声明的变量让我感到很困惑。
代码如下:

var _ FileInfo = FileInfoInternal{}
var _ FileInfo = &FileInfoInternal{}

我不知道这些声明的含义,希望能得到一些帮助。

英文:

When I read a copy of the docker/distribution source code, I find there are variables declared which make me quite confused.
The code is:

var _ FileInfo = FileInfoInternal{}
var _ FileInfo = &FileInfoInternal{}

I don't know what the declare mean, and hope to get some help.

答案1

得分: 32

FAQ中可以得知:

你可以通过尝试赋值来要求编译器检查类型T是否实现了接口I:

type T struct{}
var _ I = T{}   // 验证T是否实现了I接口。

在这种情况下,下划线_代表不需要的变量名(从而防止出现"声明但未使用"的错误)。

更一般的情况在规范中有说明:

下划线提供了一种忽略赋值语句右侧值的方法:

_ = x       // 计算x但忽略它
x, _ = f()  // 计算f()但忽略第二个结果值

通过测试FileInfoInternal{}&FileInfoInternal{},你可以检查接口是否使用值接收器实现。值接收器可以接受值和指针,而指针接收器只能使用指针,第一个赋值语句使用值将失败。

实际上,第二个测试&FileInfoInternal{}是不需要的(在评论中作者已经确认),因为第一个测试将通过值接收器而失败于指针接收器。因此,第二个测试是多余的。

这篇文章很好地解释了值接收器和指针接收器之间的区别以及它们的使用方式。

英文:

From the FAQ:

> You can ask the compiler to check that the type T implements the
> interface I by attempting an assignment:
>
> type T struct{}
> var _ I = T{} // Verify that T implements I.

In this case the blank identifier _ stands for the variable name which is not needed here (and thus prevents a "declared but not used" error).

And more general from the spec:

> The blank identifier provides a way to ignore right-hand side values
> in an assignment:
>
> _ = x // evaluate x but ignore it
> x, _ = f() // evaluate f() but ignore second result value

By testing both FileInfoInternal{} and &FileInfoInternal{} you check if the interface is implemented with a value receiver. A value receiver will accept both a value and a pointer whereas the pointer receiver will only work with a pointer and the first assignment by value will fail.

The second test with &FileInfoInternal{} is not actually needed (as confirmed by the author in the comments) since the first test will pass with a value receiver and fail with a pointer received. Thus the second test is redundant.

This is an excellent article that explains the difference between value and pointer receivers and how they are used very well.

答案2

得分: 1

FileInfo 是一个接口,代码检查 FileInfoInternal 是否实现了这个接口。

英文:

FileInfo is an interface and the code checks whether FileInfoInternal implements this interface.

huangapple
  • 本文由 发表于 2015年5月21日 15:56:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/30367803.html
匿名

发表评论

匿名网友

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

确定