乐趣区

关于golang:生产环境遇到一个-Go-问题整组人都懵逼了

微信搜寻【脑子进煎鱼了】关注这一只爆肝煎鱼。本文 GitHub github.com/eddycjy/blog 已收录,有我的系列文章、材料和开源 Go 图书。

大家好,我是煎鱼。

前段时间正在疯狂写代码的时候,忽然有一个读者给我提了一个问题,让我有了肯定的趣味:

我还是比拟感兴趣的,因为是生产环境、有代码,且整组人都懵逼的问题。

在征求了小伙伴的意见后,明天分享进去,大家也思考一下起因,一起躲避这个“坑”。

案例一

代码示例如下:

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 "脑子进煎鱼了"}

请思考一下,这段程序的输入后果是什么

该程序所调用的 GetErr 办法所返回的是 nil,而内部判断是 e == nil,因而最终的输入后果是 true,对吗?

输入后果如下:

2021/04/04 08:39:04 false

答案是:false。

案例二

代码示例如下:

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() {}

请思考一下,这段程序的输入后果是什么

该程序调用了 GetApp 办法,该办法返回的是 nil,因而其赋值的 base 也是 nil。因而判断 base == nil 的最终输入后果是 <nil>true,对吗?

输入后果如下:

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

答案是:<nil> 和 false。

为什么

为什么,这两段 Go 程序是怎么回事 … 也太反直觉了?其背地的起因实质上还是对 Go 语言中 interface 的基本原理的了解。

在案例一中,尽管 GetErr 办法的确是返回了 nil,返回的类型也是具体的 *MyErr 类型。然而其接管的变量却不是具体的构造类型,而是 error 类型:

var e error
e = GetErr()

在 Go 语言中,error 类型实质上是 interface:

type error interface {Error() string
}

因而兜兜转转又回到了 interface 类型的问题,interface 不是单纯的值,而是 分为类型和值

所以传统认知的此 nil 并非彼 nil,必须得类型和值同时都为 nil 的状况下,interface 的 nil 判断才会为 true

在案例一中,联合代码逻辑,更合乎场景的是:

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

输入后果就会是 true。

在案例二中,也是一样的后果,起因也是 interface。不论是 error 接口(interface),还是自定义的接口,背地原理统一,天然也就后果统一了。

总结

明天这篇文章,相当于是《Go 面试题:Go interface 的一个“坑”及原理剖析》的变形了,毕竟是生产环境的代码革新而来,更贴合实在的理论场景。

下意识的直觉有时候不是相对正确的,咱们要正确的了解 Go 语言中的那些知识点,能力更好地实现早上班的现实和愿景。

若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就 ,各位的 点赞 就是煎鱼创作的最大能源,感激反对。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,回复【000】有我筹备的一线大厂面试算法题解和材料;本文 GitHub github.com/eddycjy/blog 已收录,欢送 Star 催更。

退出移动版