接口
golang的interface由两种结构实现:eface和iface
1.eface 其实empty interface的意思
type eface struct{
type *_type // 表示数据类型
data unsfae.Pointer // 指向数据地址的指针
}
eface结构很简单,只有两个字段,一个表示interface的数据源类型,一个表示值
type其实就是被赋值给接口的那个变量的类型
- 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两个对象
反射有三个法则:
- 反射可以从接口映射到反射对象
- 反射可以从反射对象映射到接口
- 只有值可以修改(指针类型),才能通过反射修改它