Go 浅析interface

本文深入解析Go语言中interface的数据结构,包括eface和iface的区别,以及itab和_type的作用。讲解了interface如何存储值类型和指针类型,并详细介绍了_type结构,包括size、hash、kind等字段的含义。此外,还阐述了interfacetype如何表示接口声明的函数信息。通过对这些概念的理解,有助于深入掌握Go语言的接口机制。
摘要由CSDN通过智能技术生成

interface 的数据结构

eface 和 iface

源码:


type iface struct {
	tab  *itab
	data unsafe.Pointer
}

type eface struct {
	_type *_type
	data  unsafe.Pointer
}

在这里插入图片描述

  • eface 表示空的 interface{}
  • iface 表示至少带有一个函数的 interface

data

  • data是一个指针类型,指向被赋值对象 (或者说用来保存实际变量的地址)

因为一个interface{}可以接收值类型和指针类型,所以这里还是分成两种情况

  • 如果实际类型是值类型,interface 会在堆上为这个值分配一块内存,然后 data 指向拷贝后的对象。
  • 如果实际类型是指针类型,会拷贝指针,就相当于直接指向被赋值的对象

itab

源码:

// layout of Itab known to compilers
// allocated in non-garbage-collected memory
// Needs to be in sync with
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
type itab struct {
	inter *interfacetype
	_type *_type
	hash  uint32 // copy of _type.hash. Used for type switches.
	_     [4]byte
	fun   [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
}

在这里插入图片描述
itab 表示 interface 和 实际类型的转换信息。对于每个 interface 和实际类型,只要在代码中存在引用关系, go 就会在运行时为这一对具体的 <Interface, Type> 生成 itab 信息。

  • inter 指向对应的 interface 的类型信息。
  • type 和 eface 中的一样,指向的是实际类型的描述信息 _type
  • fun 为函数列表,表示对于该特定的实际类型而言,interface 中所有函数的地址。

_type

源码(GOROOT/src/runtime/type.go):

// Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
// ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
// ../reflect/type.go:/^type.rtype.
// ../internal/reflectlite/type.go:/^type.rtype.
type _type struct {
	size       uintptr
	ptrdata    uintptr // size of memory prefix holding all pointers
	hash       uint32
	tflag      tflag
	align      uint8
	fieldAlign uint8
	kind       uint8
	// function for comparing objects of this type
	// (ptr to object A, ptr to object B) -> ==?
	equal func(unsafe.Pointer, unsafe.Pointer) bool
	// gcdata stores the GC type data for the garbage collector.
	// If the KindGCProg bit is set in kind, gcdata is a GC program.
	// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
	gcdata    *byte
	str       nameOff
	ptrToThis typeOff
}

在这里插入图片描述
_type 表示类型信息。每个类型的 _type 信息由编译器在编译时生成。其中:

  • size 为该类型所占用的字节数量。
  • kind 表示类型的种类,如 bool、int、float、string、struct、interface 等。
  • str 表示类型的名字信息,它是一个 nameOff(int32) 类型,通过这个 nameOff,可以找到类型的名字字符串
  • 灰色的 extras 对于基础类型(如 bool,int, float 等)是 size 为 0 的,它为复杂的类型提供了一些额外信息。例如为 struct 类型提供 structtype,为 slice 类型提供 slicetype 等信息。
  • 灰色的 ucom 对于基础类型也是 size 为 0 的,但是对于 type Binary int 这种定义或者是其它复杂类型来说,ucom 用来存储类型的函数列表等信息。
  • 注意 extras 和 ucom 的圆头箭头,它表示 extras 和 ucom 不是指针,它们的内容位于 _type 的内存空间中。
    interfacetype

interfacetype

源码(GOROOT/src/runtime/type.go):

type interfacetype struct {
	typ     _type
	pkgpath name
	mhdr    []imethod
}

interfacetype 也并没有什么神奇的地方,只是 _type 为 interface 类型提供的另一种信息罢了。 它包括这个 interface 所申明的所有函数信息。

总结

在这里插入图片描述

参考

https://zhuanlan.zhihu.com/p/60983066

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值