Go中下划线(空白标识符)的含义

This question already has an answer here:

As I was reading the Go docs I found this:

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.

I don't understand what the _ is used for and I've seen it in other assignments but cannot understand what it means. Digging deeper I found that it's called "blank identifier" but I don't understand the use case they put:

_ = x // evaluate x but ignore it

Go idioms still feel a little alien to me so I'm trying to understand why I would want to do something like this.

</div>

_ is a special identifier you can assign anything to but never read from. In the first example you gave:

var _ I = T{}

There is no way to access this variable so it will be optimised out of the resulting program. However, it could cause a compile error if the type T is not assignable to the interface I. So in this case it is being used as a static assertion about a type.

The second case is more common. While it might seem strange to throw away the result of a function call, it can make more sense in functions with multiple returns. Consider a function foo that returns two values but you're only interested in the first? You can use _ to ignore the second:

a, _ = foo()

You could get the same effect by creating another variable to hold the unwanted return value, but this feature means you don't need to worry about picking a unique name for it.

“There are only two hard things in Computer Science: cache invalidation and naming things”. Tim Bray quoting Phil Karlton

This is about not having to name things.

In Go, when you don't want to use a or foo as an example variable name, you can use _. That's it! They could have written var a I = T{}, the result would have been the same (except that unused variables are an error in Go).

For other uses of the blank identifier, read Effective Go.

This is common in languages that allow multiple return values. There are situations where you don't actually care about one of the return values.

For example, in Go, it is common to return an error. If for some reason you don't care about that error, you can choose to ignore it:

value, _ := methodThatReturnsValueAndError()

If however, you assign it and don't use it, there is a compiler error:

value, err := methodThatReturnsValueAndError()
// if you don't use "err" .. its an error

In simple words _ is an ignored value. Go doesn't permit unused local variables and throws a compilation error if you try to do so. So you trick compiler saying "please ignore this value" by placing a _

For example:

// Here range of os.Args returns index, value
for index, arg := range os.Args[1:] {
    fmt.Println(arg)
}

Here Go throws compilation error because you are not using index (un used local variable) at all in the loop. Now you should make index to _ to say compiler to ignore it.

for _, arg := range os.Args[1:] {
    fmt.Println(arg)
}

The Go compiler pretty much disallows variables that are declared but not used. Like so,

for i, myvalue := range myvar {
    total += mvalue
}

The given code will show an error somewhat in this context -> "declared but not used".
Hence, we solve it using the following snippet:

for _, myvalue := range x {
    total += myvalue
}


As for the import part, it's about importing a package solely by its side-effects.
Please refer on this link.