二、Go语言Interface

在理解了如何使用Go语言的interface之后,了解其内部实现,有助于我们更好的使用这套机制。

iface和eface都是实现Go语言interface底层的两个结构体。区别在iface描述的是包含方法的接口,而eface则是不包含任何方法的空接口:intrerface{}。

eface

先从较简单的eface看起,空接口eface结构体比较简单, 由两个属性构成,一个是类型信息_type,一个是数据信息data,其结构体声明如下:

  1. type eface struct {
  2. _type *_type
  3. data unsafe.Pointer
  4. }

_type字段描述了空接口所承载实例的类型,data字段描述了实例的值。
深度理解Go语言之interface - 图1


其中_type是GO语言中所有类型的公共描述,Go语言几乎所有的数据结构都可以抽象成 _type,是所有类型的公共描述,type负责决定data应该如何解释和操作,type的结构代码如下:

  1. type _type struct {
  2. // 类型大小
  3. size uintptr
  4. ptrdata uintptr
  5. // 类型的 hash 值
  6. hash uint32
  7. // 类型的 flag,和反射相关
  8. tflag tflag
  9. // 内存对齐相关
  10. align uint8
  11. fieldalign uint8
  12. // 类型的编号,有bool, slice, struct 等等等等
  13. kind uint8
  14. alg *typeAlg
  15. // gc 相关
  16. gcdata *byte
  17. str nameOff
  18. ptrToThis typeOff
  19. }

Go 语言各种数据类型都是在 _type 字段的基础上,增加一些额外的字段来进行管理的:

  1. type arraytype struct {
  2. typ _type
  3. elem *_type
  4. slice *_type
  5. len uintptr
  6. }
  7. type chantype struct {
  8. typ _type
  9. elem *_type
  10. dir uintptr
  11. }
  12. type slicetype struct {
  13. typ _type
  14. elem *_type
  15. }
  16. type structtype struct {
  17. typ _type
  18. pkgPath name
  19. fields []structfield
  20. }

这些数据类型的结构体定义,是反射实现的基础。

https://zhuanlan.zhihu.com/p/76354559
https://zhuanlan.zhihu.com/p/64884660