当前位置: 首页 > 后端技术 > PHP

生产环境遇到一个Go问题,全团都懵了……

时间:2023-03-29 19:26:12 PHP

微信搜索【脑洞变成炸鱼】关注这家炸肝炸鱼。本文GitHubgithub.com/eddycjy/blog已收录,附有我的系列文章、资料和开源Go书籍。大家好,我是炸鱼。前段时间在疯狂写代码的时候,突然有个读者问了我一个问题,让我产生了兴趣:我还是比较感兴趣的,因为是生产环境,有代码,整个群都在纠结这个问题。征求了小伙伴们的意见后,今天分享出来。大家也应该想一想原因,一起避开这个“坑”。案例一的代码示例如下:func(m*MyErr)Error()string{return"我脑子炸了"}请大家想一想,这个程序的输出是什么?这个程序调用的GetErr方法返回nil,外部判断是e==nil,所以最后输出的是true吧?输出如下:2021/04/0408:39:04false答案是:false。案例二的代码示例如下:typeBaseinterface{do()}typeAppstruct{}funcmain(){varbaseBasebase=GetApp()log.Println(base)log.Println(base==nil)}funcGetApp()*App{returnnil}func(a*App)do(){}请想一想,这个程序的输出是什么?程序调用GetApp方法,返回nil,所以它赋值的基数也是nil。所以base==nil的最终输出是和true,对吧?输出如下:2021/04/0408:59:002021/04/0408:59:00false答案是:和false。为什么为什么,这两个围棋程序到底是怎么回事……这么反直觉?其背后的原因本质上是对Go语言中接口基本原理的理解。在情况1中,虽然GetErr方法确实返回了nil,但是返回的类型也是一个特定的*MyErr类型。但是它接收到的变量并不是一个具体的结构类型,而是一个错误类型:vareerror=GetErr()在Go语言中,错误类型本质上是一个接口:typeerrorinterface{error()string}这样绕来绕去回到接口类型的问题,接口不是简单的值,而是分为类型和值。所以按照传统的认知,这个nil不是另一个nil。只有类型和值同时为nil时,接口的nil判断才会为真。案例一,结合代码逻辑,更适合场景:vare*MyErre=GetErr()log.Println(e==nil)输出会为true。情况2,结果是一样的,原因也是interface。不管是错误接口(interface)还是自定义接口,其背后的原理都是一样的,结果自然也是一样的。总结今天的文章,相当于对《Go 面试题:Go interface 的一个 “坑” 及原理分析》的一次改造。毕竟是生产环境的代码改造,更适合真实的实际场景。有时潜意识的直觉并不是绝对正确的。我们需要正确理解Go语言中的知识点,才能更好地实现早日下班的理想和愿景。如有任何问题,欢迎在评论区反馈交流。最好的关系是相互成就。您的好评是创作炸鱼最大的动力。感谢您的支持。文章持续更新中,微信搜索【脑补炸鱼】即可阅读,回复【000】一线大厂面试算法方案和资料我都准备好了;本文已收录在GitHubgithub.com/eddycjy/blog,欢迎Star提醒。