专栏首页Golang语言社区【Go 语言社区】Golang中interface判断nil问题

【Go 语言社区】Golang中interface判断nil问题

在示例中,我们定义一个interface名为Stringer,同时定义一个符合其定义的Binary类型:

type Stringer interface {
    String() string
}

type Binary uint64
func (i Binary) String() string {
    return strconv.Uitob64(i.Get(), 2)
}

func (i Binary) Get() uint64 {
    return uint64(i)
}

func ToString(any interface{}) string {

    if v, ok := any.(Stringer); ok {
        return v.String()

    }
    switch v := any.(type) {
    case int:
        return strconv.Itoa(v)



    case float:



        return strconv.Ftoa(v, 'g', -1)



    }



    return "???"



}

复制代码

如果将一个Binary类型的变量b b=Binary(200)赋值给一个interface类型的值,排除内存优化的因素,将会形成以下的结构:

可以看到,interface变量由代表类型的itable和代表值的data来表示<itable, data>。 itable中保留的仅有Stringer类型包含的方法,其余Binary的方法并不在interface变量中可见。 data变量保存的是原数据b的一份拷贝,而不是简单的引用。

Golang中的nil:

由定义可知:

  1. var nil Type // Type must be a pointer, channel, func, interface, map, or slice type

复制代码

nil is a predeclared identifier representing the zero value for a pointer, channel, func, interface, map, or slice type.

判断interface为nil:

只有当interface为零值,即<itable, data>=<nil, nil>时,才能等于nil。

在上面的例中,如有有这样一个方法:

func isNil(s Stringer) {

        defer func() {

                if e := recover(); e != nil {

                        fmt.Printf("panic in isNil(), err:%v\n", e)
                }  

        }()

        if s == nil {

                fmt.Printf("judge1:s(%v) == nil\n", s)

                return

        }  
        if reflect.ValueOf(s).IsNil() {
                fmt.Printf("judge2:s(%v) reflect nil\n", s)
                return
        }  

        fmt.Printf("s(%v) pass\n", s)
}

  • isNil(nil)将会输出judge1 输入的nil将会被赋值成<nil, nil>的interface,可以用==nil来判断
  • var b *Binary; isNil(b)将会输出judge2 输入的b被赋值成<type=*Binary, value=nil>类型的interface(*Binary和Binary都能满足Stringer接口定义),不能==nil,而reflect.ValueOf(s)返回了具体类型的reflect.Value表示,此处即为*Binary的reflect.Value表示,isNil接受interface类型判断为nil
  • var b Binary; isNil(b)将会输出panix in isNil() 输入的b被赋值成<type=Binary, value=Binary(0)类型的interface,而reflect.ValueOf(s)返回了具体类型的reflect.Value表示,此处即为Binary(0)的reflect.Value表示,而reflect.Value.isNil只接受“ a chan, func, interface, map, pointer, or slice value”,故panic

本文分享自微信公众号 - Golang语言社区(Golangweb)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2016-02-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 理解Go语言的nil

    最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频。

    李海彬
  • Golang语言社区--golang 进度下载文件

    大家好,我是Golang社区主编彬哥,本篇给大家转载一篇关于文件下载相关的文章。

    李海彬
  • go知名第三方包ssdb

    因为beego中cache模块中使用了ssdb,所以准备学习下ssdb (1)ssdb简介 (2)ssdb的基本操作 (3)gossdb怎么使用?

    李海彬
  • 使用sniff 轻松抓取kubernetes pod的数据报文

    之前我们在k8s上进行pod级别的抓包,一般要好几步才能实现,参见这里:https://blog.51cto.com/lee90/2432209

    二狗不要跑
  • 理解Go语言的nil

    最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频。

    李海彬
  • 编程小知识之 Lua 长度运算符(#)

    Lua 中的长度运算符(#)可以用于获取 table 的"长度",举个简单的例子:

    用户2615200
  • Go语言 nil 的作用

    最近在油管上面看了一个视频:Understanding nil,挺有意思,这篇文章就对视频做一个归纳总结,代码示例都是来自于视频。

    我的小碗汤
  • go 判定对象为nil

    但是如果参数是一个interface,那情况就不同了。Interface包含类型还有值两个属性。比如:

    超级大猪
  • 算法:链表之环形链表

    该类题目的核心点在于如何判断是环形链表,核心思想是:两个人在环上跑步,跑的快的早晚会追上跑的慢的。

    灰子学技术
  • net/rpc

    比如我们在服务器注册一个对象,这个对象可以作为一项服务被暴露,服务的名字就是该对象的类型名,注册之后,对象的导出方法就可以被远程访问。服务端可以注册多个不同类型...

    酷走天涯

扫码关注云+社区

领取腾讯云代金券