WeChat search
The brain is in the fried fishPay attention to this fried fish with fried liver. In this paper,
GitHub
github.com/eddycjy/blogIs included, with my series of articles, materials, and open source GO books.

Hello, everyone. I’m Fried Fish.

Some time ago, when I was frantically writing code, a reader asked me a question that got me interested:

I was interested because it was a production environment, there was code, and the whole group was overwhelmed.

After soliciting my friends’ opinions, I want to share them with you today, so that you can think about the reasons and avoid this “pit” together.

Case a

The code example is as follows:

type MyErr struct { Msg string } func main() { var e error e = GetErr() log.Println(e == nil) } func GetErr() *MyErr { Return nil} func (m *MyErr) Error() string {return "brain in the fried fish"}

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

The GetErr method called by this program returns nil, and the external judgment is e == nil, so the final output is true, right?

The output is as follows:

2021/04/04 08:39:04 false

The answer is false.

Case 2

The code example is as follows:

type Base interface {
    do()
}

type App struct {
}

func main() {
    var base Base
    base = GetApp()
    
    log.Println(base)
    log.Println(base == nil)
}

func GetApp() *App {
    return nil
}
func (a *App) do() {}

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

The program calls the getApp method, which returns nil, so the base to which it is assigned is nil. So base == nil will result in

and true, right?

The output is as follows:

2021/04/04 08:59:00 <nil>
2021/04/04 08:59:00 false

The answer is:

and false.

why

Why, what’s going on with these two GO programs… Too counterintuitive? The reason behind this is essentially an understanding of the basic principles of interface in the Go language.

In Case 1, although the GetErr method does indeed return nil, the type returned is also the specific * myErr type. However, the variable it receives is not a concrete structure type, but an Error type:

var e error
e = GetErr()

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

type error interface {
    Error() string
}

So this goes round and round again to the problem of interface types, interfaces are not just values, they are divided into types and values.

So this nil is not that nil, the nil of an interface is true only if the type and the value are both nil.

In Case 1, combined with code logic, what is more appropriate for the scenario is:

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

The output will be true.

In case 2, the same result, the reason is also interface. Whether it is an Error interface or a custom interface, the principle behind it is the same, so the result will be the same.

conclusion

Today’s article is equivalent to the deformation of GO interview question: A “pit” and principle analysis of GO Interface. After all, it is transformed from the code of the production environment, which is more in line with the real actual scene.

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

If you have any questions, please feel free to give feedback and exchange in the comment section. The best relationship is mutual achievement. Your thumb up is the biggest motivation for Fried Fish’s creation.

The article is updated continuously, you can search “brain into fried fish” to read, reply [
000I have prepared the first line of big factory interview algorithm solutions and information; In this paper,
GitHub
github.com/eddycjy/blogHas been included, welcome STAR to urge more.