golang interface接口和反射的原理

233 阅读1分钟

接口

golang的interface由两种结构实现:eface和iface

1.eface 其实empty interface的意思

type eface struct{
    type *_type // 表示数据类型
    data unsfae.Pointer // 指向数据地址的指针
}

eface结构很简单,只有两个字段,一个表示interface的数据源类型,一个表示值

type其实就是被赋值给接口的那个变量的类型

  1. iface的结构
type iface struct {
	tab  *itab
	data unsafe.Pointer //指向原始数据指针
}

其中tab存放类型、方法等信息

type itab struct {
        //inter 和 _type 确定唯一的 _type类型
	inter *interfacetype //接口自身定义的类型信息,用于定位到具体interface类型
	_type *_type  // 接口实际指向值的类型信息-实际对象类型,用于定义具体interface类型
	hash  uint32 //_type.hash的拷贝,用于快速查询和判断目标类型和接口中类型是一致
	_     [4]byte
	fun   [1]uintptr //动态数组,接口方法实现列表(方法集),即函数地址列表,按字典序排序
                         //如果数组中的内容为空表示 _type 没有实现 inter 接口
}

itab的数据类型,type是赋值给接口的变量的数据类型

inter 里面存放是接口的描述信息以及结构的方法列表

fun是动态类型实现了接口的那些方法地址

反射

反射的实现主要是通过type和value实现的,和interface的结构很类似

可以通过reflect.Typeof 和 reflect.Valueof获取type和value两个对象

反射有三个法则:

  1. 反射可以从接口映射到反射对象
  2. 反射可以从反射对象映射到接口
  3. 只有值可以修改(指针类型),才能通过反射修改它

i6448038.github.io/2020/02/15/…