IDC

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

作者:admin 2021-07-07 我要评论

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

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)
微信搜索【脑子进煎鱼了】关注这一只爆肝煎鱼。本文 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 催更。

本文转自网络,版权归原作者所有,原文链接:https://segmentfault.com/a/1190000040305603

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • []*T *[]T *[]*T 傻傻分不清楚

    []*T *[]T *[]*T 傻傻分不清楚

  • B站,牛逼!

    B站,牛逼!

  • 如何保证 Serverless 业务部署更新的一

    如何保证 Serverless 业务部署更新的一

  • Room 中的数据库自动迁移功能

    Room 中的数据库自动迁移功能

腾讯云代理商
海外云服务器