开发者

深入了解Golang interface{}的底层原理实现

开发者 https://www.devze.com 2022-12-03 14:44 出处:网络 作者: 1个俗人
目录前言interface数据结构ifaceeface总结前言 在 Go 语言没有泛型之前,接口可以作为一种替代实现,也就是万物皆为的 interface。那到底 interface 是怎么设计的底层结构呢?下面咱们透过底层分别看一下这两种类型的
目录
  • 前言
  • interface数据结构
  • iface
    • eface
  • 总结

    前言

    Go 语言没有泛型之前,接口可以作为一种替代实现,也就是万物皆为的 interface。那到底 interface 是怎么设计的底层结构呢?下面咱们透过底层分别看一下这两种类型的接口原理。感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

    interface数据结构

    golang中的接口分为带方法的接口和空接口。 带方法的接口在底层用androidiface表示,空接口的底层则是eface表示。下面咱们透过底层分别看一下这两种数据结构。

    iface

    iface表示的是包含方法的inte开发者_Go培训rface;例如:

    type Test interface{
        test()
    }

    底层源代码是:

    //runtime/runtime2.go
    
    //非空接口
    type iface struct {
    	tab  *itab
    	data unsafe.Pointer //data是指向真实数据的指针
    }
    type itab struct {
    	inter  *interfacetype //描述接口自己的类型
    	_type  *_type         //接口内部存储的具体数据的真实类型
    	link   *itab
    	hash   uint32 // copy of _type.hash. Used for type switches.
    	bad    bool   // type does not implement interface
    	inhash bool   // has this itab been added to hash?
    	unused [2]byte
    	fun    [1]uintptr // fun是指向方法集的指针。它用于动态调度。
    }
    
    //runtime/type.go
    type _type struct {
    	size       uintptr
    	ptrdata    uintptr // sizandroide 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    *www.devze.combyte
    	str       nameOff
    	ptrToThis typeOff
    }

    和eface相同的是都有指向具体数据的指针data字段。 不同的是_type变成了tab。

    • hash 是对 _type.hash 的拷贝,当我www.devze.com们想将 interface 类型转换成具体类型时,可以使用该字段快速判断目标类型和具体类型 runtime._type 是否一致;
    • fun 是一个动态大小的数组,它是一个用于动态派发的虚函数表,存储了一组函数指针。虽然该变量被声明成大小固定的数组,但是在使用时会通过原始指针获取其中的数据;

    深入了解Golang interface{}的底层原理实现

    eface

    eface顾名思义 empty interface,代表的是不包含方法的interface,例如:

    type Test interface {}
    

    因为空接口不包含任何方法,所以它的结构也很简单,底层源代码是:

    //空接口
    type eface struct {
    	_type *_type         //接口内部存储的具体数据的真实类型
    	data  unsafe.Pointer //data是指向真实数据的指针
    }
    
    //runtime/type.go
    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 androidbit 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
    }

    eface 结构体主要包含两个字段,共16字节。

    • _type:这个是运行时 runtime._type 指针类型,表示数据类型
    • data: 表示的数据指针

    深入了解Golang interface{}的底层原理实现

    总结

    Go语言底层对非空interface和空interface实现上做了区分。空interface的底层结构是eface结构。它与iface的区别在于,它拥有的不再是 *itab类型数据,而是 _type 类型的数据。是因为,eface面向的是空的interface数据,既然是空的interface,那么只需要用 *_type 代表类型,data字段指向具体数据即可。这里的 *_type 是此interface代表的数据的类型。

    到此这篇关于深入了解Golang interface{}的底层原理实现的文章就介绍到这了,更多相关Golang interface{}内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号