Wechat search [brain into fried fish] follow this fried fish with fried liver. In this paper, making github.com/eddycjy/blo… Already included, there are my series of articles, materials and open source Go books.

Hello, I’m fried fish.

Some time ago, while I was coding madly, a reader asked me a question that aroused my interest:

It’s interesting to me because it’s production, it’s code, and the whole team is confused.

After soliciting the opinions of my friends, I would like to share it with you today. We can also think about the reasons and avoid this “pit” together.

Case a

A code example is as follows:

type MyErr struct {
    Msg string
}

func main(a) {
    var e error
    e = GetErr()
    log.Println(e == nil)}func GetErr(a) *MyErr {
    return nil
}

func (m *MyErr) Error(a) string {
    return "Brain goes into fried fish."
}
Copy the code

Think about it, what is the output of this program?

The GetErr method that this program calls returns nil, and the external judgment is E == nil, so the final output is true, right?

The following output is displayed:

2021/04/04 08:39:04 false
Copy the code

The answer is false.

Case 2

A code example is as follows:

type Base interface {
    do()
}

type App struct{}func main(a) {
    var base Base
    base = GetApp()
    
    log.Println(base)
    log.Println(base == nil)}func GetApp(a) *App {
    return nil
}
func (a *App) do(a) {}
Copy the code

Think about it, what is the output of this program?

The program calls the GetApp method, which returns nil, so its assigned base is nil. So the final output for base == nil is

and true, right?

The following output is displayed:

2021/04/04 08:59:00 <nil>
2021/04/04 08:59:00 false
Copy the code

The answers are:

and false.

why

Why, what happened to the two Go programs… How counterintuitive is that? The reason behind this is essentially an understanding of the basic principles of interface in Go.

In case 1, although the GetErr method did return nil, it returned a specific *MyErr type. The variable it receives is not a concrete structure type, but an error:

var e error
e = GetErr()
Copy the code

In the Go language, the error type is essentially interface:

type error interface {
    Error() string
}
Copy the code

So this comes back to the interface type, which is not just a value, but a type and a value.

Therefore, the traditional perception of nil is that this nil is not that nil, and the nil judgment of the interface can only be true if the type and value are both nil.

In case 1, combined with the code logic, the scenario is more appropriate:

var e *MyErr
e = GetErr()
log.Println(e == nil)
Copy the code

The output will be true.

In case 2, the same result is obtained, and the reason is also interface. Whether it is an error interface or a custom interface, the principle behind it is the same, and the result is the same.

conclusion

Today’s article, quite like “Go interview question: Go interface a” pit “and principle analysis of the deformation, after all, is the production environment of the code transformation, more suitable for the real actual scene.

Subconscious intuition is sometimes not absolutely correct, we should correctly understand those knowledge points in Go language, in order to better realize the ideal and vision of leaving work early.

If you have any questions, welcome feedback and communication in the comments section. The best relationship is mutual achievement. Your praise is the biggest motivation for the creation of fried fish, thank you for your support.

This article is constantly updated. You can search “Brain into fried fish” on wechat to read it. Reply [000] There are the answers and materials for the interview algorithm of first-line big factories that I prepared. In this paper, making github.com/eddycjy/blo… Star has been included, welcome to urge more.