1. 接口的底层结构体
iface和eface,区别在于iface描述的接口包含方法,而eface则是不包含任何方法的空接口:interface{}
1.1 iface源码
type iface struct {
tab *itab
data unsafe.Pointer
}
type itab struct {
inter *interfacetype
_type *_type
link *itab
hash uint32 // copy of _type.hash. Used for type switches.
bad bool // type does not implement interface
inhash bool // has this itab been added to hash?
unused [2]byte
fun [1]uintptr // variable sized
}
说明:iface内部维护两个指针,tab指向一个itab实体, 表示接口的类型以及赋给这个接口的实体类型。data指向接口具体的值,一般而言是一个指向堆内存的指针
interfacetype类型:
type interfacetype struct {
typ _type
pkgpath name
mhdr []imethod
}
iface结构体图示:

1.2 eface的源码
type eface struct {
_type *_type // 动态类型
data unsafe.Pointer
}
说明:eface维护了一个 _type 字段,表示空接口所承载的具体的实体类型,data描述了具体的值
举例:
f, _ := os.Open("text.txt") // f => *os.File
var i1 interface{}
i1 = f
说明:eface的data字段的值就是f,_type就是*os.File类型的元数据
验证:
func TestInterface(t *testing.T) {
f, _ := os.Open("text.txt")
fmt.Printf("f pointer:%p\n", f)
fmt.Println("==========")
var i1 interface{}
i1 = f
ptr2 := unsafe.Pointer(&i1)
opt2 := (*[2]unsafe.Pointer)(ptr2)
fmt.Println("interface: ", opt2[0], opt2[1])
}
输出:
f pointer:0xc00000e038 ========== interface: 0x11091e0 0xc00000e038
说明: i1的interface{}变量的data值与f的地址是一样的。