Explain the use of underline in Golang in detail

  • 2020-06-23 00:34:59
  • OfStack

In Golang, _ (underline) is a special identifier. A few days ago, gin source code, see an interesting use. Although the summary blog on the Internet has a lot of, but always a little lack, so there is this 1, easy to look up later.

Used in import

This is a common use when guiding packages, especially when using mysql in a project or using pprof for performance analysis, for example


import _ "net/http/pprof"
import _ "github.com/go-sql-driver/mysql"

In this usage, the call is made in the package init() Function that initializes the imported package, but does not use any other functionality in the package.

Used in return values

This is also a common usage. Functions in Golang typically return multiple values of 1, and err usually returns the last value. However, sometimes there is a value in the return value of a function that we don't care about, how we receive that value but don't use it, the code compiles an error, so we need to ignore it. Such as


for _, val := range Slice {}
_, err := func()

In the variable

We all know that the interface of Go language is non-intrusive, not as heavy as java and c++. As long as a structure implements all functions defined by the interface, we say that the interface implements the interface. There is a special name for this behavior, duck typing. When a bird is seen walking like a duck, swimming like a duck, and chirping like a duck, the bird is called a duck.


type I interface {
  Sing()
}

type T struct { 
}

func (t T) Sing() {
}

type T2 struct {  
}

func (t *T2) Sing() {
}

//  Compiled by 
var _ I = T{}
//  Compiled by 
var _ I = &T{}

//  Compilation fails 
var _ I = T2{}
//  Compiled by 
var _ I = &T2{}

The underscore here is used to determine whether the structure implements an interface. If it does not, it will expose a problem at compile time. Without this judgment, the compiler will not report an error using interface methods that the structure does not implement.

It can be seen that only the third of the above four judgments failed at compile time, and the error is reported as follows:

[

./test.go:27:5: cannot use T2 literal (type T2) as type I in assignment:
T2 does not implement I (Sing method has pointer receiver)

]

Why is that? If you look at the code above, T To achieve the Sing Method, *T2 To achieve the Sing Methods.

As we all know, the Go language is passed by value.

The for T2 Say, call Sing Method, copy 1 copy, and then fetch the address through which the original call structure can not be found, but receiver is a pointer, indicating that the call is to change the caller's internal variables, obviously, to T2 Type calls are not complete for this purpose, so you need to report an error here. And in order to &T2 call Sing Method, can, therefore does not report an error.

And for T No error will be reported whether there is a pointer call or not, and in fact, the Go language is implemented automatically *T the Sing Methods.

Of course, these are my personal understanding, if not, welcome to correct.


Related articles: