天天看点

Go语言--接口的内部实现1 接口内部实现

1 接口内部实现

毫无疑问,接口是Go语言类型系统的灵魂,是Go语言实现多态和反射的基础。前面我们结束了接口的基本概念和用法,定义接口只需要简单声明一个方法集合即可,定义新类型时不需要显式地声明要实现的接口,接口的使用也很简单。但这一切语言特性的背后是语言设计者们的智慧:把复杂留给自己,把简单留给用户。

接口的底层是如何实现的?如果实现动态调用?接口的动态调用到底需要多大的额外开销?这是我们需要弄清楚的问题。

<备注> 基于 go1.15版本。

1.1 数据结构

接口变量必须初始化才有意义,没有初始化的接口变量的默认值是nil。具体类型实例传递给接口称为接口的初始化。接口的初始化过程中,编译器通过特定的数据结构描述这个过程。非空接口的内部数据结构如下:

// src/runtime/runtime2.go
type iface struct {
    tab  *itab            //itab存放类型及方法指针信息
    data unsafe.Pointer   //数据信息
}
           

非空接口的初始化过程就是初始化一个 iface 类型的结构体。

  • itab:是一个结构体,用来存放接口自身类型和并绑定的实例类型及实例相关的函数指针,具体内容下面会详细介绍。
  • 数据指针data:指向接口绑定的实例的副本,接口的初始化也是一种值拷贝。data指向具体的实例数据,如果传递给接口的是值类型,则data指向的