有任何问题或建议,请及时交流碰撞。我的公众号是【脑补成炸鱼】,GitHub地址:https://github.com/eddycjy。大家好,我是炸鱼。前几天在读者交流群看到一个朋友对接口的使用有很多疑惑。无独有偶,在网上也看到有小伙伴在Go面试的时候被问到:今天特地分享一下,让大家避开这个坑。例1第一个例子,代码如下:funcmain(){varvinterface{}v=(*int)(nil)fmt.Println(v==nil)}你认为输出会是什么?答案是:为什么假的不是真的。显然,它们已被强制设置为零。Go编译器有问题吗?例2第二个例子,代码如下:funcmain(){vardata*bytevarininterface{}fmt.Println(data,data==nil)fmt.Println(in,in==nil)in=datafmt.Println(in,in==nil)}你认为输出会是什么?答案是:truetruefalse这就更奇怪了,为什么刚刚声明的data和in变量确实输出为nil,而且判断结果也是true。变量数据一赋值给变量in,世界怎么就变了呢?输出仍然为零,但评估变为错误。令人惊讶的是,结果与上面的第一个示例相似。接口判断和想象的不一样的根本原因是接口不是指针类型,虽然看起来很像,误导了很多人。再深入到接口,接口中有两种数据结构:runtime.eface结构:表示一个空接口,不包含任何方法,也称为空接口。runtime.iface结构:表示包含方法的接口。看两者对应的底层数据结构:typeefacestruct{_type*_typedataunsafe.Pointer}typeifacestruct{tab*itabdataunsafe.Pointer}你会发现interface不是一个简单的值,而是分为类型和价值。所以按照传统的认知,这个nil不是另一个nil。只有类型和值同时为nil时,接口的nil判断才会为真。解决方案与其说是一种解决方案,不如说是一种巧妙的打破局面的方法。在不改变类型的情况下,其中一种方法是使用反射,如下代码所示:iinterface{})bool{vi:=reflect.ValueOf(i)ifvi.Kind()==reflect.Ptr{returnvi.IsNil()}returnfalse}使用反射判断nil的值,在反射中有会对接口类型做特殊处理,最终输出结果为:true,达到效果。对于其他的方法,就是改变原来的程序逻辑,比如:对value做一个nil判断,然后返回到界面设置。返回具体值类型而不是接口。总结Go接口是Go语言中最常用的类型之一。如果你习惯了iferr!=nil,很容易踩进去。我建议你多关注一下。如果你想对界面有更深入的了解,可以看我的深度解析文章:《一文吃透 Go 语言解密之接口 interface》。各位小伙伴踩过或遇到过界面相关的“坑”吗?欢迎大家在下方留言讨论分享。一起冲刺吧!我的公众号分享Go语言、微服务架构和奇怪的系统设计。欢迎关注我的公众号与我交流交流。最好的关系是相互成就。您的喜欢是创作炸鱼最大的动力。感谢您的支持。