golang的interface

黑魔术师 · · 782 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1.golang的interface设计
golang的interface设计,从是否有方法的角度,分为iface和eface。然后所有的interface内又包含type和value,其中type包含都是结构体rtype,且都继承自接口Type。

不同的是,对与纯值interface,eface来说,type就是rtype类型,对于有方法的interface,iface来说,type是用itab来表示。

itab是运行时虚表,目的是支持golang的接口自动继承特性,其中的interfacetype为包含imethod的虚表,类型断言时比较的就是itab。

2.golang的interface底层实现(1.10.3)。
先看接口的底层实现,,在runtime中还有一份实现,暂时还不明白空接口和接口之间如何完成转换。

type iface struct {
   tab  *itab
   data unsafe.Pointer
}

type eface struct {
   _type *_type
   data  unsafe.Pointer
}
 
// layout of Itab known to compilers
// allocated in non-garbage-collected memory
// Needs to be in sync with
// ../cmd/compile/internal/gc/reflect.go:/^func.dumptypestructs.
type itab struct {
   inter *interfacetype
   _type *_type
   hash  uint32 // copy of _type.hash. Used for type switches.
   _     [4]byte
   fun   [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}
 
type interfacetype struct {
   typ     _type
   pkgpath name
   mhdr    []imethod
}
 
// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
// ../cmd/compile/internal/gc/reflect.go:/^func.dcommontype and
// ../reflect/type.go:/^type.rtype.
type _type struct {
   size       uintptr
   ptrdata    uintptr // size of memory prefix holding all pointers
   hash       uint32
   tflag      tflag
   align      uint8
   fieldalign uint8
   kind       uint8
   alg        *typeAlg
   // gcdata stores the GC type data for the garbage collector.
   // If the KindGCProg bit is set in kind, gcdata is a GC program.
   // Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
   gcdata    *byte
   str       nameOff
   ptrToThis typeOff
}

代码在reflect包中也有一份抽象的实现。核心有 emptyInterface、 nonEmptyInterface、 rtype这个类。

// emptyInterface is the header for an interface{} value.
type emptyInterface struct {
   typ  *rtype
   word unsafe.Pointer
}
 
// nonEmptyInterface is the header for an interface value with methods.
type nonEmptyInterface struct {
   // see ../runtime/iface.go:/Itab
   itab *struct {
      ityp *rtype // static interface type
      typ  *rtype // dynamic concrete type
      hash uint32 // copy of typ.hash
      _    [4]byte
      fun  [100000]unsafe.Pointer // method table
   }
   word unsafe.Pointer
}
 
// rtype is the common implementation of most values.
// It is embedded in other, public struct types, but always
// with a unique tag like `reflect:"array"` or `reflect:"ptr"`
// so that code cannot convert from, say, *arrayType to *ptrType.
//
// rtype must be kept in sync with ../runtime/type.go:/^type._type.
type rtype struct {
   size       uintptr
   ptrdata    uintptr  // number of bytes in the type that can contain pointers
   hash       uint32   // hash of type; avoids computation in hash tables
   tflag      tflag    // extra type information flags
   align      uint8    // alignment of variable with this type
   fieldAlign uint8    // alignment of struct field with this type
   kind       uint8    // enumeration for C
   alg        *typeAlg // algorithm table
   gcdata     *byte    // garbage collection data
   str        nameOff  // string form
   ptrToThis  typeOff  // type for pointer to this type, may be zero
}

有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:黑魔术师

查看原文:golang的interface

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

782 次点击  
加入收藏 微博
上一篇:golang的reflect
下一篇:golang的goroutine
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传