网络编程
位置:首页>> 网络编程>> Go语言>> 深入了解Golang interface{}的底层原理实现

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

作者:1个俗人  发布时间:2024-05-05 09:31:13 

标签:Golang,interface

前言

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

interface数据结构

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

iface

iface表示的是包含方法的interface;例如:

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 // 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
}

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

  • hash 是对 _type.hash 的拷贝,当我们想将 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 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
}

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

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

  • data: 表示的数据指针

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

来源:https://juejin.cn/post/7157625818456260644

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com