社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
在示例中,我们定义一个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的一份拷贝,而不是简单的引用。
由定义可知:
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为零值,即<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) } |
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!