golang中interface判断nil问题 - Go语言中文社区

golang中interface判断nil问题


interface数据的表示

参阅http://research.swtch.com/interfaces

在示例中,我们定义一个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:

由定义可知:

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:%vn", e)
                }  
        }()
        if s == nil {
                fmt.Printf("judge1:s(%v) == niln", s)
                return
        }  
        if reflect.ValueOf(s).IsNil() {
                fmt.Printf("judge2:s(%v) reflect niln", s)
                return
        }  
        fmt.Printf("s(%v) passn", 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
版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/xiaohu50/article/details/50318963
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 23:15:13
  • 阅读 ( 2461 )
  • 分类:Go

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢