golang踩坑 3.接口值是否等于nil

火山方舟向量数据库大模型

就像雨总会停,雾总会散,同样地没有谁会一直失败。

  1. 前言

这篇文章我们就来聊聊接口值等于nil这种常见类型零值的判断,有些童鞋在用的过程中难免会犯错,犯错之后又不知如何改正,那么接下来我就给大家把这个坑填上。

  1. 接口值是否等于nil

具体类型的nil值, 赋值给接口值变量后, 被判定不为nil。

  
func main() {  
  
    // *bytes.Buffer, 零值为nil  
    var b *bytes.Buffer  
  
    if b == nil {  
        fmt.Println("外面的b等于nil")  
    } else {  
        fmt.Println("外面的b不等于nil")  
    }  
  
    f := func(b io.Writer) {  
        if b == nil {  
            fmt.Println("里面的b等于nil")  
        } else {  
            fmt.Println("里面的b不等于nil")  
        }  
    }  
  
    // 把b传入函数  
    f(b)  
  
}  
  
//===========输出===============  
  
外面的b等于nil  
里面的b不等于nil  
  

原因:

golang中的接口值, 除了有自己的类型type外, 还有动态类型(dynamic type)和动态值(dynamic value). 接口值如果要被判断为nil, 需要动态类型和动态值都为nil. 可以通过fmt的"%T", “%v"观察动态类型和动态值。

  1. 打印动态类型和动态值

  
func main() {  
  
    var b *bytes.Buffer  
  
    fmt.Printf("外面的b类型为%T\n", b)  
    fmt.Printf("外面的b值为%v\n", b)  
  
    if b == nil {  
        fmt.Println("外面的b等于nil")  
    } else {  
        fmt.Println("外面的b不等于nil")  
    }  
  
    fmt.Println("")  
  
    f := func(b io.Writer) {  
        fmt.Printf("里面的b类型为%T\n", b)  
        fmt.Printf("里面的b值为%v\n", b)  
        if b == nil {  
            fmt.Println("里面的b等于nil")  
        } else {  
            fmt.Println("里面的b不等于nil")  
        }  
    }  
  
    f(b)  
  
}  
  
//==============输出=================  
  
外面的b类型为*bytes.Buffer  
外面的b值为<nil>  
外面的b等于nil  
  
里面的b类型为*bytes.Buffer  
里面的b值为<nil>  
里面的b不等于nil  
  

  1. 小结

我们看到当把一个具体类型赋值给接口之后,这个接口一定不是nil,因为接口的动态类型保存着具体类型的type,但是接口的动态值可能是nil,所以只要有一个不为nil,那么接口就不是nil,这个大家要在以后的代码中谨慎一些。具体大家可以看下interface的源码实现就知道为什么了。

  1. 关注公众号

微信公众号: 堆栈future

0
0
0
0
关于作者
关于作者

文章

0

获赞

0

收藏

0

相关资源
云原生机器学习系统落地和实践
机器学习在字节跳动有着丰富业务场景:推广搜、CV/NLP/Speech 等。业务规模的不断增大对机器学习系统从用户体验、训练效率、编排调度、资源利用等方面也提出了新的挑战,而 Kubernetes 云原生理念的提出正是为了应对这些挑战。本次分享将主要介绍字节跳动机器学习系统云原生化的落地和实践。
相关产品
评论
未登录
看完啦,登录分享一下感受吧~
暂无评论