Why declare like “var _ I = T{}” and “var _ I = &T

2020-05-23 18:15发布

问题:

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:

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:

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