Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 541
JCheng Avatar asked May 21 '15 07:05

JCheng


2 Answers

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.

like image 195
IamNaN Avatar answered Nov 07 '22 21:11

IamNaN


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

like image 1
Salvador Dali Avatar answered Nov 07 '22 22:11

Salvador Dali