ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] ## interface底层结构 ![](https://img.kancloud.cn/5c/8c/5c8c8f3b98e5f907ff475cf6255c63db_705x332.png) * `runtime.eface` 结构体:表示不包含任何方法的空接口,也称为 empty interface。 * `runtime.iface` 结构体:表示包含方法的接口。 **只有当interface 的 type和data 都是nil的时候才是nil,有一个不是nil,就不能判断是不是nil** ### runtime.eface ``` type eface struct {  _type *_type //类型  data  unsafe.Pointer // 值的指针 } //type的结构体 type _type struct {  size       uintptr  ptrdata    uintptr  hash       uint32  tflag      tflag  align      uint8  fieldAlign uint8  kind       uint8  equal func(unsafe.Pointer, unsafe.Pointer) bool  gcdata    *byte  str       nameOff  ptrToThis typeOff } ``` * size:类型的大小。 * ptrdata:包含所有指针的内存前缀的大小。 * hash:类型的 hash 值。此处提前计算好,可以避免在哈希表中计算。 * tflag:额外的类型信息标志。此处为类型的 flag 标志,主要用于反射。 * align:对应变量与该类型的内存对齐大小。 * fieldAlign:对应类型的结构体的内存对齐大小。 * kind:类型的枚举值。包含 Go 语言中的所有类型,例如:`kindBool`、`kindInt`、`kindInt8`、`kindInt16` 等。 * equal:用于比较此对象的回调函数。 * gcdata:存储垃圾收集器的 GC 类型数据。 总结一句,就是类型信息所需的信息都会存储在这里面,其中包含字节大小、类型标志、内存对齐、GC 等相关属性。而在 `eface` 来讲,其由于没有方法集的包袱,因此只需要存储类型和值信息的指针即可,非常简单。 ### runtime.iface ``` type iface struct {  tab  *itab  data unsafe.Pointer } //itab结构体 type itab struct {  inter *interfacetype  _type *_type hash  uint32   _     [4]byte  fun   [1]uintptr  } ``` * `inter`:接口的类型信息。 * `_type`:具体类型信息 * `hash`:`_type.hash` 的副本,用于目标类型和接口变量的类型对比判断。 * `fun`:底层数组,存储接口的方法集的具体实现的地址,其包含一组函数指针,实现了接口方法的动态分派,且每次在接口发生变更时都会更新。 #### interfacetype ``` type interfacetype struct {  typ     _type  pkgpath name  mhdr    []imethod } type nameOff int32 type typeOff int32 type imethod struct {  name nameOff  ityp typeOff } ``` * `_type`:接口的具体类型信息。 * `pkgpath`:接口的包(package)名信息。 * `mhdr`:接口所定义的函数列表。 总结: ![](https://img.kancloud.cn/46/16/4616efd865f85cc32fdf643550c747e3_1080x721.png)