1

生产环境遇到一个 Go 问题,整组人都懵逼了...

 2 years ago
source link: https://segmentfault.com/a/1190000040305603
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

生产环境遇到一个 Go 问题,整组人都懵逼了...

发布于 今天 04:37
English

微信搜索【脑子进煎鱼了】关注这一只爆肝煎鱼。本文 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 催更。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK