iface 和 eface 区别
iface
和eface
都是go中描述接口的底层结构体
区别在于iface
描述的接口包含方法,而eface
则不包含任何方法的空接口: interface
底层源码:
type iface struct {
tab *iteb
data unsafe.Pointer
}
type itab struct {
inter *interfacetype
_type *_type
link *itab
hash uint32
bad bool
inhash bool
unused [2]byte
fun [1]uintptr
}
iface
内部维护了两个指针,tab
指向一个itab
实体,它表示接口的类型以及赋给这个接口的实体类型。data
则指向接口的具体值,一般而言上一个指向堆内存的指针
itab
结构体: _type
字段描述了实体的类型,包括内存对齐的方式,大小等;inter
字段则描述了接口的类型。fun
字段放置和接口方法对应方法对应的具体数据类型的方法地址,实现接口调用方法的动态分派,一般在每次给接口赋值发生转换时会更新此表,或者直接拿缓存的itab
interfacetype
类型,它描述的是接口类型
type interfacetype struct {
type _type // go语言各种数据类型的结构体
pkgath name // 记录了接口的包名
mhdr []imethod //接口所定义的函数列表
}
eface
type eface struct {
_type *_type //空接口所承载的具体的实体类型
data unsafe.Pointer // 描述了具体的值
}
例子:
package main
import "fmt"
func main(){
x:=200
var any interfacer{}=x
fmt.Println(any)
g:=Gopher("go")
var c coder =g
fmt.Println(g)
}
type coder interface {
code()
debug()
}
type Gopher struct {
language string
}
func (p Gopher) code() {
fmt.Println("写代码")
}
func (p Gopher) debug(){
fmt.Println("调试")
}
执行命令
go tool compile -S main.go
补充说明 _type
结构体:
type _type struct {
// 类型大小
size uintptr
prtdata uintptr
//hash值
hash uint32
// 类型的flag 和反射相关
tflag tflag
//内存对齐相关
align uint8
fieldalign uint8
// 类型的编号,有 bool,slice,struct 等等
kind uint8
alg *typeAlg
//gc相关
gcdata *byte
str nameOff
ptrToThis typeOff
}